findOrder method
Finds the order value for the given object using annotation-aware resolution.
This method implements the comprehensive order resolution strategy that makes this comparator unique. It examines various sources of order information in a specific precedence sequence.
Resolution Precedence:
-
Direct Objects:
PriorityOrdered
implementations (highest precedence)Ordered
implementations- Raw integer values
-
Class Objects:
@Order
annotation on the classOrdered
interface implementation- Fallback to
Ordered.LOWEST_PRECEDENCE
-
Source Objects:
@Order
annotation on the source element
-
Executable Objects (Methods/Constructors):
@Order
annotation- Parameter count as natural ordering (fewer parameters first)
-
Fallback Strategy:
- For unknown types, attempt to get class and recurse
- Final fallback to
Ordered.LOWEST_PRECEDENCE
Parameters:
obj
: The object to find order for (Class, Source, Executable, or direct object)
Returns:
The resolved order value, or null
if no specific order could be determined
Example:
final comparator = AnnotationAwareOrderComparator();
// Check annotated class
@Order(42)
class MyService {}
final order1 = comparator.findOrder(Class<MyService>());
print(order1); // 42
// Check Ordered implementation
class OrderedService implements Ordered {
@override int get order => 100;
}
final order2 = comparator.findOrder(Class<OrderedService>());
print(order2); // 100
// Check method with @Order annotation
class Component {
@Order(10)
void highPriorityMethod() {}
}
final method = Class<Component>().getDeclaredMethod('highPriorityMethod');
final order3 = comparator.findOrder(method);
print(order3); // 10
// Check method without annotation (uses parameter count)
class AnotherComponent {
void methodWithParams(String a, int b) {} // 2 parameters
}
final method2 = Class<AnotherComponent>().getDeclaredMethod('methodWithParams');
final order4 = comparator.findOrder(method2);
print(order4); // 2
Implementation
int? findOrder(Object? obj) {
if (obj == null) return Ordered.LOWEST_PRECEDENCE;
if (obj is Class) {
final cls = obj;
// First priority: @Order annotation on class
if (cls.hasDirectAnnotation<Order>()) {
final ann = cls.getDirectAnnotation<Order>();
if (ann != null) return ann.value;
}
// Second priority: Ordered interface implementation
final ordered = Class<Ordered>();
if (ordered.isAssignableFrom(cls)) {
final instance = cls.getNoArgConstructor()?.newInstance();
if (instance != null && instance is PriorityOrdered) {
return instance.getOrder();
} else if (instance != null && instance is Ordered) {
return instance.getOrder();
}
}
} else if (obj is Source) {
// @Order annotation on source elements
if (obj.hasDirectAnnotation<Order>()) {
final ann = obj.getDirectAnnotation<Order>();
if (ann != null) return ann.value;
}
} else if (obj is Executable) {
// @Order annotation on executables
if (obj.hasDirectAnnotation<Order>()) {
final ann = obj.getDirectAnnotation<Order>();
if (ann != null) return ann.value;
}
// Natural ordering for methods based on parameter count
if (obj is Method) {
final method = obj;
return method.getParameters().length;
}
// Natural ordering for constructors based on parameter count
if (obj is Constructor) {
final constructor = obj;
return constructor.getParameters().length;
}
} else if (obj is PriorityOrdered) {
// Direct PriorityOrdered implementation (highest precedence)
return obj.getOrder();
} else if (obj is Ordered) {
// Direct Ordered implementation
return obj.getOrder();
} else if (obj is int) {
// Raw integer order value
return obj;
} else {
// Fallback: try to get class and recurse
return findOrder(obj.getClass());
}
return null;
}