Pivot
  1. Pivot
  2. PIVOT-703

Allow BXMLSerializer.bind() to access superclass fields

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Not a Problem
    • Affects Version/s: 2.0
    • Fix Version/s: 2.0.1
    • Component/s: core-beans
    • Labels:
    • Environment:
      Windows XP SP3, Java version "1.6.0_23"

      Description

      Loading a standard object from a BXML file (such as a "Dialog") so that the code to bind to a superclass when the Bindable interface is present on the serialized object is not exercised, allow "bind" to find public fields in a superclass by calling "getField()" if "getDeclaredField()" fails.

      1. diff
        2 kB
        Roger Whitcomb

        Activity

        Hide
        Roger Whitcomb added a comment -

        Here is a patch to implement this change – required refactoring the loop inside "bind" to loop over keys in the namespace and call either "getDeclaredField()" or "getField()" on the name.

        Show
        Roger Whitcomb added a comment - Here is a patch to implement this change – required refactoring the loop inside "bind" to loop over keys in the namespace and call either "getDeclaredField()" or "getField()" on the name.
        Hide
        Niclas Hedhman added a comment -

        Current and proposed implementation seems to only worry about public fields (no setAccessible() present, but is perhaps done elsewhere) so getFields() is most convenient to do, but there is value in doing injection on private fields;

        Proper private field injection should loop through the super-classes, do getDeclaredFields() and for each field it needs to inject do a field.setAccessible(true) and field.set( obj, value ).

        What is important to know about reflection;

        • getDeclaredFields() only gets all field on the queried class. getFields() returns all public fields in the queried class and its superclasses.
        • Without setAccessible(true), it is not possible to set private members.
        Show
        Niclas Hedhman added a comment - Current and proposed implementation seems to only worry about public fields (no setAccessible() present, but is perhaps done elsewhere) so getFields() is most convenient to do, but there is value in doing injection on private fields; Proper private field injection should loop through the super-classes, do getDeclaredFields() and for each field it needs to inject do a field.setAccessible(true) and field.set( obj, value ). What is important to know about reflection; getDeclaredFields() only gets all field on the queried class. getFields() returns all public fields in the queried class and its superclasses. Without setAccessible(true), it is not possible to set private members.
        Hide
        Niclas Hedhman added a comment - - edited

        To get all private fields of a class and its superclasses;

        public static List<Field> fieldsOf( Class clazz )

        { List<Field> fields = new ArrayList<Field>(); addFields( clazz, fields ); return fields; }

        private static void addFields( Class clazz, List<Field> fields )
        {
        if( clazz != null && !clazz.equals( Object.class ) )

        { fields.addAll( asList( clazz.getDeclaredFields() ) ); addFields( clazz.getSuperclass(), fields ); }

        }

        Show
        Niclas Hedhman added a comment - - edited To get all private fields of a class and its superclasses; public static List<Field> fieldsOf( Class clazz ) { List<Field> fields = new ArrayList<Field>(); addFields( clazz, fields ); return fields; } private static void addFields( Class clazz, List<Field> fields ) { if( clazz != null && !clazz.equals( Object.class ) ) { fields.addAll( asList( clazz.getDeclaredFields() ) ); addFields( clazz.getSuperclass(), fields ); } }
        Hide
        Roger Whitcomb added a comment -

        I am withdrawing this request since the two parameter "bind(Object object, Class<?> type)" method works fine to walk the superclass chain myself and bind to all the superclass variables.

        Show
        Roger Whitcomb added a comment - I am withdrawing this request since the two parameter "bind(Object object, Class<?> type)" method works fine to walk the superclass chain myself and bind to all the superclass variables.
        Hide
        Roger Whitcomb added a comment -

        Using the "bind(Object object, Class<?> type)" method is perfect to do what I needed.

        Show
        Roger Whitcomb added a comment - Using the "bind(Object object, Class<?> type)" method is perfect to do what I needed.

          People

          • Assignee:
            Unassigned
            Reporter:
            Roger Whitcomb
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Time Tracking

              Estimated:
              Original Estimate - 1h
              1h
              Remaining:
              Remaining Estimate - 1h
              1h
              Logged:
              Time Spent - Not Specified
              Not Specified

                Development