11/*
2- * Copyright 2002-2014 the original author or authors.
2+ * Copyright 2002-2015 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
2222import java .sql .SQLException ;
2323import java .util .HashMap ;
2424import java .util .HashSet ;
25+ import java .util .Locale ;
2526import java .util .Map ;
2627import java .util .Set ;
2728
@@ -136,9 +137,51 @@ public void setMappedClass(Class<T> mappedClass) {
136137 }
137138 }
138139
140+ /**
141+ * Get the class that we are mapping to.
142+ */
143+ public final Class <T > getMappedClass () {
144+ return this .mappedClass ;
145+ }
146+
147+ /**
148+ * Set whether we're strictly validating that all bean properties have been mapped
149+ * from corresponding database fields.
150+ * <p>Default is {@code false}, accepting unpopulated properties in the target bean.
151+ */
152+ public void setCheckFullyPopulated (boolean checkFullyPopulated ) {
153+ this .checkFullyPopulated = checkFullyPopulated ;
154+ }
155+
156+ /**
157+ * Return whether we're strictly validating that all bean properties have been
158+ * mapped from corresponding database fields.
159+ */
160+ public boolean isCheckFullyPopulated () {
161+ return this .checkFullyPopulated ;
162+ }
163+
164+ /**
165+ * Set whether we're defaulting Java primitives in the case of mapping a null value
166+ * from corresponding database fields.
167+ * <p>Default is {@code false}, throwing an exception when nulls are mapped to Java primitives.
168+ */
169+ public void setPrimitivesDefaultedForNullValue (boolean primitivesDefaultedForNullValue ) {
170+ this .primitivesDefaultedForNullValue = primitivesDefaultedForNullValue ;
171+ }
172+
173+ /**
174+ * Return whether we're defaulting Java primitives in the case of mapping a null value
175+ * from corresponding database fields.
176+ */
177+ public boolean isPrimitivesDefaultedForNullValue () {
178+ return this .primitivesDefaultedForNullValue ;
179+ }
180+
181+
139182 /**
140183 * Initialize the mapping metadata for the given class.
141- * @param mappedClass the mapped class.
184+ * @param mappedClass the mapped class
142185 */
143186 protected void initialize (Class <T > mappedClass ) {
144187 this .mappedClass = mappedClass ;
@@ -147,9 +190,9 @@ protected void initialize(Class<T> mappedClass) {
147190 PropertyDescriptor [] pds = BeanUtils .getPropertyDescriptors (mappedClass );
148191 for (PropertyDescriptor pd : pds ) {
149192 if (pd .getWriteMethod () != null ) {
150- this .mappedFields .put (pd .getName (). toLowerCase ( ), pd );
193+ this .mappedFields .put (lowerCaseName ( pd .getName ()), pd );
151194 String underscoredName = underscoreName (pd .getName ());
152- if (!pd .getName (). toLowerCase ( ).equals (underscoredName )) {
195+ if (!lowerCaseName ( pd .getName ()).equals (underscoredName )) {
153196 this .mappedFields .put (underscoredName , pd );
154197 }
155198 this .mappedProperties .add (pd .getName ());
@@ -160,18 +203,20 @@ protected void initialize(Class<T> mappedClass) {
160203 /**
161204 * Convert a name in camelCase to an underscored name in lower case.
162205 * Any upper case letters are converted to lower case with a preceding underscore.
163- * @param name the string containing original name
206+ * @param name the original name
164207 * @return the converted name
208+ * @since 4.2
209+ * @see #lowerCaseName
165210 */
166- private String underscoreName (String name ) {
211+ protected String underscoreName (String name ) {
167212 if (!StringUtils .hasLength (name )) {
168213 return "" ;
169214 }
170215 StringBuilder result = new StringBuilder ();
171- result .append (name .substring (0 , 1 ). toLowerCase ( ));
216+ result .append (lowerCaseName ( name .substring (0 , 1 )));
172217 for (int i = 1 ; i < name .length (); i ++) {
173218 String s = name .substring (i , i + 1 );
174- String slc = s . toLowerCase ( );
219+ String slc = lowerCaseName ( s );
175220 if (!s .equals (slc )) {
176221 result .append ("_" ).append (slc );
177222 }
@@ -183,45 +228,14 @@ private String underscoreName(String name) {
183228 }
184229
185230 /**
186- * Get the class that we are mapping to.
187- */
188- public final Class <T > getMappedClass () {
189- return this .mappedClass ;
190- }
191-
192- /**
193- * Set whether we're strictly validating that all bean properties have been
194- * mapped from corresponding database fields.
195- * <p>Default is {@code false}, accepting unpopulated properties in the
196- * target bean.
197- */
198- public void setCheckFullyPopulated (boolean checkFullyPopulated ) {
199- this .checkFullyPopulated = checkFullyPopulated ;
200- }
201-
202- /**
203- * Return whether we're strictly validating that all bean properties have been
204- * mapped from corresponding database fields.
205- */
206- public boolean isCheckFullyPopulated () {
207- return this .checkFullyPopulated ;
208- }
209-
210- /**
211- * Set whether we're defaulting Java primitives in the case of mapping a null value
212- * from corresponding database fields.
213- * <p>Default is {@code false}, throwing an exception when nulls are mapped to Java primitives.
214- */
215- public void setPrimitivesDefaultedForNullValue (boolean primitivesDefaultedForNullValue ) {
216- this .primitivesDefaultedForNullValue = primitivesDefaultedForNullValue ;
217- }
218-
219- /**
220- * Return whether we're defaulting Java primitives in the case of mapping a null value
221- * from corresponding database fields.
231+ * Convert the given name to lower case.
232+ * By default, conversions will happen within the US locale.
233+ * @param name the original name
234+ * @return the converted name
235+ * @since 4.2
222236 */
223- public boolean isPrimitivesDefaultedForNullValue ( ) {
224- return primitivesDefaultedForNullValue ;
237+ protected String lowerCaseName ( String name ) {
238+ return name . toLowerCase ( Locale . US ) ;
225239 }
226240
227241
@@ -243,7 +257,7 @@ public T mapRow(ResultSet rs, int rowNumber) throws SQLException {
243257
244258 for (int index = 1 ; index <= columnCount ; index ++) {
245259 String column = JdbcUtils .lookupColumnName (rsmd , index );
246- PropertyDescriptor pd = this .mappedFields .get (column .replaceAll (" " , "" ). toLowerCase ( ));
260+ PropertyDescriptor pd = this .mappedFields .get (lowerCaseName ( column .replaceAll (" " , "" )));
247261 if (pd != null ) {
248262 try {
249263 Object value = getColumnValue (rs , index , pd );
@@ -254,15 +268,14 @@ public T mapRow(ResultSet rs, int rowNumber) throws SQLException {
254268 try {
255269 bw .setPropertyValue (pd .getName (), value );
256270 }
257- catch (TypeMismatchException e ) {
258- if (value == null && primitivesDefaultedForNullValue ) {
259- logger .debug ("Intercepted TypeMismatchException for row " + rowNumber +
260- " and column '" + column + "' with value " + value +
261- " when setting property '" + pd .getName () + "' of type " + pd .getPropertyType () +
262- " on object: " + mappedObject );
271+ catch (TypeMismatchException ex ) {
272+ if (value == null && this .primitivesDefaultedForNullValue ) {
273+ logger .debug ("Intercepted TypeMismatchException for row " + rowNumber + " and column '" +
274+ column + "' with null value when setting property '" + pd .getName () +
275+ "' of type " + pd .getPropertyType () + " on object: " + mappedObject );
263276 }
264277 else {
265- throw e ;
278+ throw ex ;
266279 }
267280 }
268281 if (populatedProperties != null ) {
0 commit comments