Skip to content

Commit d46b6f8

Browse files
Sort signal types
1 parent 13c2baa commit d46b6f8

File tree

1 file changed

+33
-3
lines changed

1 file changed

+33
-3
lines changed

server/src/main/kotlin/io/spine/server/route/RoutingMethodMap.kt

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import io.spine.server.entity.Entity
3838
import io.spine.string.simply
3939
import java.lang.reflect.Method
4040
import java.lang.reflect.Modifier
41+
import java.util.SortedMap
4142

4243
/**
4344
* The abstract base for classes for scanning routing methods defined in an entity class.
@@ -60,7 +61,7 @@ public sealed class RoutingMethodMap<I: Any>(
6061

6162
protected val idClass: Class<*> = GenericParameter.ID.argumentIn(this::class.java)
6263

63-
internal val methods: Map<Class<out SignalMessage>, RoutingMethod<I, *, *, *>>
64+
internal val methods: SortedMap<Class<out SignalMessage>, RoutingMethod<I, *, *, *>>
6465

6566
init {
6667
val collecting = mutableMapOf<Class<out SignalMessage>, RoutingMethod<I, *, *, *>>()
@@ -74,8 +75,7 @@ public sealed class RoutingMethodMap<I: Any>(
7475
val firstParam = method.parameters[0].type as Class<out SignalMessage>
7576
collecting[firstParam] = createMethod(method)
7677
}
77-
//TODO:2025-01-09:alexander.yevsyukov: Add sorting by interfaces.
78-
methods = collecting.toMap()
78+
methods = collecting.toSortedMap(SignalClassComparator())
7979
}
8080

8181
@Suppress("ReturnCount")
@@ -123,6 +123,36 @@ public sealed class RoutingMethodMap<I: Any>(
123123
}
124124
}
125125

126+
/**
127+
* Sorts classes of signal messages putting more abstract types further.
128+
*/
129+
private class SignalClassComparator : Comparator<Class<out SignalMessage>> {
130+
131+
@Suppress("ReturnCount")
132+
override fun compare(o1: Class<out SignalMessage>, o2: Class<out SignalMessage>): Int {
133+
if (o1 == o2) {
134+
return 0
135+
}
136+
// An interface should come after a class in the sorting.
137+
if (o1.isInterface && !o2.isInterface) {
138+
return 1
139+
}
140+
if (!o1.isInterface && o2.isInterface) {
141+
return -1
142+
}
143+
// Both are either classes or interfaces.
144+
// The one that is more abstract further in sorting.
145+
if (o1.isAssignableFrom(o2)) {
146+
return 1
147+
}
148+
if (o2.isAssignableFrom(o1)) {
149+
return -1
150+
}
151+
// Sort alphabetically then.
152+
return o1.canonicalName.compareTo(o2.canonicalName)
153+
}
154+
}
155+
126156
/**
127157
* Collects routing methods for commands.
128158
*/

0 commit comments

Comments
 (0)