/* * Copyright (c) 2015 Mockito contributors * This program is made available under the terms of the MIT License. */ package org.mockito.internal.util.reflection; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; /** * Sort fields in an order suitable for injection, by name with superclasses * moved after their subclasses. */ public class SuperTypesLastSorter { private SuperTypesLastSorter() { } /** * Return a new collection with the fields sorted first by name, * then with any fields moved after their supertypes. */ public static List<Field> sortSuperTypesLast(Collection<? extends Field> unsortedFields) { List<Field> fields = new ArrayList<Field>(unsortedFields); Collections.sort(fields, compareFieldsByName); int i = 0; while (i < fields.size() - 1) { Field f = fields.get(i); Class<?> ft = f.getType(); int newPos = i; for (int j = i + 1; j < fields.size(); j++) { Class<?> t = fields.get(j).getType(); if (ft != t && ft.isAssignableFrom(t)) { newPos = j; } } if (newPos == i) { i++; } else { fields.remove(i); fields.add(newPos, f); } } return fields; } private static final Comparator<Field> compareFieldsByName = new Comparator<Field>() { @Override public int compare(Field o1, Field o2) { return o1.getName().compareTo(o2.getName()); } }; }