2020import com .igormaznitsa .jbbp .exceptions .JBBPIllegalArgumentException ;
2121import com .igormaznitsa .jbbp .mapper .Bin ;
2222import com .igormaznitsa .jbbp .mapper .BinType ;
23+ import com .igormaznitsa .jbbp .mapper .JBBPMapper ;
24+ import com .igormaznitsa .jbbp .mapper .MappedFieldRecord ;
2325import com .igormaznitsa .jbbp .model .JBBPFieldInt ;
2426import com .igormaznitsa .jbbp .model .JBBPFieldLong ;
2527import com .igormaznitsa .jbbp .model .JBBPFieldShort ;
2628import com .igormaznitsa .jbbp .model .JBBPFieldString ;
2729import com .igormaznitsa .jbbp .utils .DslBinCustom ;
2830import com .igormaznitsa .jbbp .utils .JBBPUtils ;
29- import com .igormaznitsa .jbbp .utils .ReflectUtils ;
3031import java .lang .reflect .Array ;
3132import java .lang .reflect .Field ;
32- import java .lang .reflect .Modifier ;
33- import java .util .ArrayList ;
34- import java .util .Collections ;
35- import java .util .HashMap ;
3633import java .util .List ;
37- import java .util .Map ;
3834
3935/**
4036 * Abstract class to collect, order and process all fields in a mapped class.
4137 * since 1.1
4238 */
4339public abstract class AbstractMappedClassFieldObserver {
4440
45- /**
46- * Internal cache to keep outOrder of fields for classes for data output. It is
47- * lazy initialized field.
48- */
49- private static Map <Class <?>, Field []> cachedClasses ;
50-
5141 /**
5242 * Inside auxiliary method to read object field value.
5343 *
@@ -87,69 +77,7 @@ private static void assertFieldArray(final Field field) {
8777 protected void processObject (final Object obj , Field field , final Object customFieldProcessor ) {
8878 JBBPUtils .assertNotNull (obj , "Object must not be null" );
8979
90- Field [] orderedFields = null ;
91-
92- final Map <Class <?>, Field []> fieldz ;
93- if (cachedClasses == null ) {
94- fieldz = new HashMap <>();
95- cachedClasses = fieldz ;
96- } else {
97- fieldz = cachedClasses ;
98- synchronized (cachedClasses ) {
99- orderedFields = fieldz .get (obj .getClass ());
100- }
101- }
102-
103- if (orderedFields == null ) {
104- // find out the outOrder of fields and fields which should be serialized
105- final List <Class <?>> listOfClassHierarchy = new ArrayList <>();
106- final List <OrderedField > fields = new ArrayList <>();
107-
108- Class <?> current = obj .getClass ();
109- while (current != java .lang .Object .class ) {
110- listOfClassHierarchy .add (current );
111- current = current .getSuperclass ();
112- }
113-
114- for (int i = listOfClassHierarchy .size () - 1 ; i >= 0 ; i --) {
115- final Class <?> clazzToProcess = listOfClassHierarchy .get (i );
116- final Bin clazzAnno = clazzToProcess .getAnnotation (Bin .class );
117-
118- for (Field f : clazzToProcess .getDeclaredFields ()) {
119- if (!ReflectUtils .isPotentiallyAccessibleField (f )) {
120- f = ReflectUtils .makeAccessible (f );
121- }
122-
123- final int modifiers = f .getModifiers ();
124- if (Modifier .isTransient (modifiers ) || Modifier .isStatic (modifiers ) || f .getName ().indexOf ('$' ) >= 0 ) {
125- continue ;
126- }
127-
128- Bin fieldAnno = f .getAnnotation (Bin .class );
129- fieldAnno = fieldAnno == null ? clazzAnno : fieldAnno ;
130- if (fieldAnno == null ) {
131- continue ;
132- }
133-
134- fields .add (new OrderedField (fieldAnno .outOrder (), f ));
135- }
136- }
137-
138- Collections .sort (fields );
139-
140- orderedFields = new Field [fields .size ()];
141- for (int i = 0 ; i < fields .size (); i ++) {
142- orderedFields [i ] = fields .get (i ).field ;
143- }
144-
145- synchronized (fieldz ) {
146- fieldz .put (obj .getClass (), orderedFields );
147- }
148- }
149-
150- if (field != null && !ReflectUtils .isPotentiallyAccessibleField (field )) {
151- field = ReflectUtils .makeAccessible (field );
152- }
80+ final List <MappedFieldRecord > orderedFields = JBBPMapper .findAffectedFields (obj );
15381
15482 final Bin clazzAnno = obj .getClass ().getAnnotation (Bin .class );
15583 final DslBinCustom clazzCustomAnno = obj .getClass ().getAnnotation (DslBinCustom .class );
@@ -158,20 +86,14 @@ protected void processObject(final Object obj, Field field, final Object customF
15886
15987 this .onStructStart (obj , field , clazzAnno == null ? fieldAnno : clazzAnno );
16088
161- for (final Field f : orderedFields ) {
162- Bin binAnno = f .getAnnotation (Bin .class );
163- if (binAnno == null ) {
164- binAnno = f .getDeclaringClass ().getAnnotation (Bin .class );
165- if (binAnno == null ) {
166- throw new JBBPIllegalArgumentException ("Can't find any Bin annotation to use for " + f + " field" );
167- }
168- }
89+ for (final MappedFieldRecord rec : orderedFields ) {
90+ Bin binAnno = rec .binAnnotation ;
16991
17092 if (binAnno .custom () && customFieldProcessor == null ) {
171- throw new JBBPIllegalArgumentException ("The Class '" + obj .getClass ().getName () + "' contains the field '" + f .getName () + "\' which is a custom one, you must provide a JBBPCustomFieldWriter instance to save the field." );
93+ throw new JBBPIllegalArgumentException ("The Class '" + obj .getClass ().getName () + "' contains the field '" + rec . mappingField .getName () + "\' which is a custom one, you must provide a JBBPCustomFieldWriter instance to save the field." );
17294 }
17395
174- processObjectField (obj , f , binAnno , customFieldProcessor );
96+ processObjectField (obj , rec . mappingField , binAnno , customFieldProcessor );
17597 }
17698
17799 this .onStructEnd (obj , field , clazzAnno == null ? fieldAnno : clazzAnno );
@@ -690,52 +612,4 @@ protected void onArrayEnd(final Object obj, final Field field, final Bin annotat
690612
691613 }
692614
693- /**
694- * Inside JBBPOut.Bin command creates cached list of fields of a saved class,
695- * the method allows to reset the inside cache.
696- */
697- public void resetInsideClassCache () {
698- final Map <Class <?>, Field []> fieldz = cachedClasses ;
699- if (fieldz != null ) {
700- synchronized (fieldz ) {
701- fieldz .clear ();
702- }
703- }
704- }
705-
706- /**
707- * An Auxiliary class to be used for class field ordering in save operations.
708- */
709- private static final class OrderedField implements Comparable <OrderedField > {
710-
711- final int order ;
712- final Field field ;
713-
714- OrderedField (final int order , final Field field ) {
715- this .order = order ;
716- this .field = field ;
717- }
718-
719- @ Override
720- public boolean equals (final Object obj ) {
721- return obj != null && (obj == this || (obj instanceof OrderedField && this .field .equals (((OrderedField ) obj ).field )));
722- }
723-
724- @ Override
725- public int hashCode () {
726- return this .order ;
727- }
728-
729- @ Override
730- public int compareTo (final OrderedField o ) {
731- final int result ;
732- if (this .order == o .order ) {
733- result = this .field .getName ().compareTo (o .field .getName ());
734- } else {
735- result = this .order < o .order ? -1 : 1 ;
736- }
737- return result ;
738- }
739- }
740-
741615}
0 commit comments