View Javadoc

1   /*
2    * $Id: OgnlFieldPopulator.java,v 1.6 2004/05/23 10:26:58 eelco12 Exp $
3    * $Revision: 1.6 $
4    * $Date: 2004/05/23 10:26:58 $
5    *
6    * ====================================================================
7    * Copyright (c) 2003, Open Edge B.V.
8    * All rights reserved.
9    * Redistribution and use in source and binary forms, with or without 
10   * modification, are permitted provided that the following conditions are met:
11   * Redistributions of source code must retain the above copyright notice, 
12   * this list of conditions and the following disclaimer. Redistributions 
13   * in binary form must reproduce the above copyright notice, this list of 
14   * conditions and the following disclaimer in the documentation and/or other 
15   * materials provided with the distribution. Neither the name of OpenEdge B.V. 
16   * nor the names of its contributors may be used to endorse or promote products 
17   * derived from this software without specific prior written permission.
18   * 
19   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
20   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
21   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
22   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
23   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
24   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
25   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
26   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
27   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
28   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
29   * THE POSSIBILITY OF SUCH DAMAGE.
30   */
31  package nl.openedge.baritus.population;
32  
33  import ognl.NoSuchPropertyException;
34  import ognl.Ognl;
35  import ognl.OgnlContext;
36  import ognl.OgnlException;
37  
38  import org.apache.commons.logging.Log;
39  import org.apache.commons.logging.LogFactory;
40  import org.infohazard.maverick.flow.ControllerContext;
41  
42  import nl.openedge.baritus.ExecutionParams;
43  import nl.openedge.baritus.FormBeanCtrlBase;
44  import nl.openedge.baritus.FormBeanContext;
45  import nl.openedge.baritus.LogConstants;
46  import nl.openedge.baritus.converters.ConversionException;
47  
48  /***
49   * OGNL populator for bean properties. Tries to set a property using OGNL.
50   * 
51   * @author Eelco Hillenius
52   * @author Sander Hofstee
53   */
54  public final class OgnlFieldPopulator extends AbstractFieldPopulator
55  {
56  
57  	private static Log populationLog = LogFactory.getLog(LogConstants.POPULATION_LOG);
58  	
59  	private final static OgnlConverterWrapper converter = new OgnlConverterWrapper();
60  	
61  	/*** context key for current locale */
62  	public final static String CTX_KEY_CURRENT_LOCALE = "__currentLocale";
63  	
64  	/*** context key for current target type */
65  	public final static String CTX_KEY_CURRENT_TARGET_TYPE = "__currentTargetType";
66  
67  	/*** context key for current execution parameters */
68  	public final static String CTX_KEY_CURRENT_EXEC_PARAMS = "__currentExecParams";
69  	
70  	/*** context key for current field name expression */
71  	public final static String CTX_KEY_CURRENT_FIELD_NAME = "__currentFieldName";
72  	
73  	/*** context key for current tried value */
74  	public final static String CTX_KEY_CURRENT_TRIED_VALUE = "__currentTriedValue";
75  	
76  	/*** context key for current converter */
77  	public final static String CTX_KEY_CURRENT_CONVERTER = "__currentConverter";
78  
79  	/***
80  	 * construct with reference to the control
81  	 * @param ctrl
82  	 */
83  	public OgnlFieldPopulator(FormBeanCtrlBase ctrl)
84  	{
85  		super(ctrl);
86  	}
87  
88  	/***
89  	 * set a property
90  	 * @param cctx maverick context
91  	 * @param formBeanContext context with instance of the form bean to set the property on
92  	 * @param name name of the property
93  	 * @param value unconverted value to set
94  	 * @throws Exception
95  	 */
96  	public boolean setProperty(
97  		ControllerContext cctx,	
98  		FormBeanContext formBeanContext,
99  		String name,
100 		Object value)
101 		throws Exception
102 	{
103 
104 		boolean success = true;
105 		Object bean = formBeanContext.getBean();
106 		
107 		ExecutionParams params = formBeanContext.getController().getExecutionParams(cctx);
108 		
109 		OgnlContext context = new OgnlContext();
110 		context.setTypeConverter(converter);
111 		context.put(CTX_KEY_CURRENT_LOCALE, formBeanContext.getCurrentLocale());
112 		context.put(CTX_KEY_CURRENT_EXEC_PARAMS, params);
113 		context.put(CTX_KEY_CURRENT_FIELD_NAME, name);
114 		
115 		// trim input string values if required
116 		if(params.isTrimStringInputValues())
117 		{
118 			if(value instanceof String)
119 			{
120 				value = ((String)value).trim();
121 			}
122 			else if(value instanceof String[])
123 			{
124 				String[] _value = (String[])value;
125 				for(int i = 0; i < _value.length; i++)
126 				{
127 					_value[i] = _value[i].trim();
128 				}
129 			}
130 		}
131 		
132 		try
133 		{
134 			Ognl.setValue(name, context, bean, value);
135 		}
136 		catch (OgnlException e)
137 		{
138 			if(e instanceof NoSuchPropertyException)
139 			{
140 				// just ignore and log warning
141 				populationLog.warn("property '" + name + "' not found for bean " + bean);
142 			}
143 			else
144 			{
145 				if(e.getReason() instanceof ConversionException)
146 				{
147 					Class targetType = (Class)context.get(CTX_KEY_CURRENT_TARGET_TYPE);
148 					value = context.get(CTX_KEY_CURRENT_TRIED_VALUE);
149 					ctrl.setConversionErrorForField(
150 						cctx, formBeanContext, targetType, name, value, e);
151 					ctrl.setOverrideField(cctx, formBeanContext, name, value, e, null);
152 					success = false;					
153 				}
154 				else
155 				{
156 					if(params.isStrictPopulationMode())
157 					{
158 						populationLog.error(e.getMessage(), e);
159 						value = context.get(CTX_KEY_CURRENT_TRIED_VALUE);
160 						formBeanContext.setError(name, e.getMessage());	
161 						ctrl.setOverrideField(cctx, formBeanContext, name, value, e, null);
162 						success = false;	
163 					}
164 					else
165 					{
166 						// just ignore and log a warning
167 						if(populationLog.isDebugEnabled())
168 						{
169 							populationLog.warn(e.getMessage(), e);						
170 						}
171 						else
172 						{
173 							populationLog.warn(e.getMessage());							
174 						}
175 					}
176 				}
177 			}
178 		}
179 		catch(ConversionException e)
180 		{
181 			Class targetType = (Class)context.get(CTX_KEY_CURRENT_TARGET_TYPE);
182 			ctrl.setConversionErrorForField(
183 				cctx, formBeanContext, targetType, name, value, e);
184 			ctrl.setOverrideField(cctx, formBeanContext, name, value, e, null);
185 			success = false;			
186 		}
187 
188 		return success;
189 
190 	}
191 
192 }