44import org .bbottema .javareflection .util .commonslang25 .StringUtils ;
55import org .bbottema .javareflection .model .FieldWrapper ;
66import org .bbottema .javareflection .model .InvokableObject ;
7+ import org .bbottema .javareflection .valueconverter .IncompatibleTypeException ;
8+ import org .bbottema .javareflection .valueconverter .ValueConversionHelper ;
79import org .jetbrains .annotations .NotNull ;
810import org .jetbrains .annotations .Nullable ;
911
1012import java .lang .reflect .Field ;
1113import java .lang .reflect .Method ;
1214import java .lang .reflect .Modifier ;
13- import java .util .Arrays ;
14- import java .util .EnumSet ;
15- import java .util .HashMap ;
16- import java .util .LinkedList ;
17- import java .util .List ;
18- import java .util .Map ;
19- import java .util .Set ;
15+ import java .util .*;
2016import java .util .regex .Pattern ;
2117
18+ import static java .util .EnumSet .allOf ;
19+ import static java .util .EnumSet .of ;
2220import static java .util .regex .Pattern .compile ;
21+ import static org .bbottema .javareflection .BeanUtils .BeanRestriction .YES_SETTER ;
22+ import static org .bbottema .javareflection .BeanUtils .BeanRestriction .YES_GETTER ;
2323
2424/**
2525 * A {@link Field} shorthand utility class used to collect fields from classes meeting Java Bean restrictions/requirements.
@@ -177,9 +177,9 @@ public static boolean methodIsBeanlike(Method method) {
177177 */
178178 @ SuppressWarnings ("WeakerAccess" )
179179 @ NotNull
180- public static Map <Class <?>, List <FieldWrapper >> collectFields (final Class <?> _class , final Class <?> boundaryMarker ,
180+ public static LinkedHashMap <Class <?>, List <FieldWrapper >> collectFields (final Class <?> _class , final Class <?> boundaryMarker ,
181181 final EnumSet <Visibility > visibility , final EnumSet <BeanRestriction > beanRestrictions ) {
182- final Map <Class <?>, List <FieldWrapper >> fields = new HashMap <>();
182+ final LinkedHashMap <Class <?>, List <FieldWrapper >> fields = new LinkedHashMap <>();
183183 final Field [] allFields = _class .getDeclaredFields ();
184184 final List <FieldWrapper > filteredFields = new LinkedList <>();
185185 for (final Field field : allFields ) {
@@ -261,4 +261,49 @@ static FieldWrapper resolveBeanProperty(final Field field, final EnumSet<BeanRes
261261 return null ;
262262 }
263263 }
264+
265+ /**
266+ * Calls the setters for the first field that matches given fieldName. Attempts to convert the value in case the type is incorrect.
267+ *
268+ * @return The actual value used in the bean setter.
269+ */
270+ @ SuppressWarnings ("ConstantConditions" )
271+ static public Object invokeBeanSetter (Object o , String fieldName , Object value ) {
272+ for (List <FieldWrapper > fieldWrappers : collectFields (o .getClass (), Object .class , allOf (Visibility .class ), of (YES_SETTER )).values ()) {
273+ for (FieldWrapper fieldWrapper : fieldWrappers ) {
274+ if (fieldWrapper .getField ().getName ().equals (fieldName ) ) {
275+ Object assignedValue = value ;
276+ try {
277+ MethodUtils .invokeMethodSimple (fieldWrapper .getSetter (), o , value );
278+ } catch (final IllegalArgumentException ie ) {
279+ try {
280+ assignedValue = ValueConversionHelper .convert (value , fieldWrapper .getField ().getType ());
281+ } catch (IncompatibleTypeException e ) {
282+ throw new RuntimeException (new NoSuchMethodException (e .getMessage ()));
283+ }
284+ MethodUtils .invokeMethodSimple (fieldWrapper .getSetter (), o , assignedValue );
285+ }
286+ return assignedValue ;
287+ }
288+ }
289+ }
290+ throw new RuntimeException (new NoSuchMethodException ("Bean setter for " + fieldName ));
291+ }
292+
293+ /**
294+ * Calls the setters for the first field that matches given fieldName. Attempts to convert the value in case the type is incorrect.
295+ *
296+ * @return The actual value used in the bean setter.
297+ */
298+ @ SuppressWarnings ("ConstantConditions" )
299+ static public Object invokeBeanGetter (Object o , String fieldName ) {
300+ for (List <FieldWrapper > fieldWrappers : collectFields (o .getClass (), Object .class , allOf (Visibility .class ), of (YES_GETTER )).values ()) {
301+ for (FieldWrapper fieldWrapper : fieldWrappers ) {
302+ if (fieldWrapper .getField ().getName ().equals (fieldName ) ) {
303+ return MethodUtils .invokeMethodSimple (fieldWrapper .getGetter (), o );
304+ }
305+ }
306+ }
307+ throw new RuntimeException (new NoSuchMethodException ("Bean getter for " + fieldName ));
308+ }
264309}
0 commit comments