Home | History | Annotate | Download | only in reflection
      1 /*
      2  * Copyright (c) 2015 Mockito contributors
      3  * This program is made available under the terms of the MIT License.
      4  */
      5 
      6 package org.mockito.internal.util.reflection;
      7 
      8 import java.lang.reflect.Field;
      9 import java.util.ArrayList;
     10 import java.util.Collection;
     11 import java.util.Collections;
     12 import java.util.Comparator;
     13 import java.util.List;
     14 
     15 /**
     16  * Sort fields in an order suitable for injection, by name with superclasses
     17  * moved after their subclasses.
     18  */
     19 public class SuperTypesLastSorter {
     20 
     21     private SuperTypesLastSorter() {
     22     }
     23 
     24     /**
     25      * Return a new collection with the fields sorted first by name,
     26      * then with any fields moved after their supertypes.
     27      */
     28     public static List<Field> sortSuperTypesLast(Collection<? extends Field> unsortedFields) {
     29         List<Field> fields = new ArrayList<Field>(unsortedFields);
     30 
     31         Collections.sort(fields, compareFieldsByName);
     32 
     33         int i = 0;
     34 
     35         while (i < fields.size() - 1) {
     36             Field f = fields.get(i);
     37             Class<?> ft = f.getType();
     38             int newPos = i;
     39             for (int j = i + 1; j < fields.size(); j++) {
     40                 Class<?> t = fields.get(j).getType();
     41 
     42                 if (ft != t && ft.isAssignableFrom(t)) {
     43                     newPos = j;
     44                 }
     45             }
     46 
     47             if (newPos == i) {
     48                 i++;
     49             } else {
     50                 fields.remove(i);
     51                 fields.add(newPos, f);
     52             }
     53         }
     54 
     55         return fields;
     56     }
     57 
     58 
     59     private static final Comparator<Field> compareFieldsByName = new Comparator<Field>() {
     60         @Override
     61         public int compare(Field o1, Field o2) {
     62             return o1.getName().compareTo(o2.getName());
     63         }
     64     };
     65 }
     66