Skip to content

Commit a2a1ab8

Browse files
committed
#32 - List<Instances> should return in order of @priority (from javax.annotations)
1 parent e17f3f5 commit a2a1ab8

File tree

7 files changed

+142
-2
lines changed

7 files changed

+142
-2
lines changed

src/main/java/io/dinject/BeanContext.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,20 @@ public interface BeanContext extends Closeable {
133133
*/
134134
<T> List<T> getBeans(Class<T> interfaceType);
135135

136+
/**
137+
* Return the list of beans that implement the interface without
138+
* sorting by priority (ignoring any Priority annotation).
139+
*/
140+
<T> List<T> getBeansUnsorted(Class<T> interfaceType);
141+
142+
/**
143+
* Sort the beans by javax.annotation.Priority annotation.
144+
*
145+
* @param list The beans to sort by priority
146+
* @return A new list of beans sorted by priority
147+
*/
148+
<T> List<T> sortByPriority(List<T> list);
149+
136150
/**
137151
* Start the context firing any <code>@PostConstruct</code> methods.
138152
*/

src/main/java/io/dinject/BootContext.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,16 @@ public <T> List<T> getBeans(Class<T> interfaceType) {
465465
return context.getBeans(interfaceType);
466466
}
467467

468+
@Override
469+
public <T> List<T> getBeansUnsorted(Class<T> interfaceType) {
470+
return context.getBeansUnsorted(interfaceType);
471+
}
472+
473+
@Override
474+
public <T> List<T> sortByPriority(List<T> list) {
475+
return context.sortByPriority(list);
476+
}
477+
468478
@Override
469479
public void start() {
470480
context.start();

src/main/java/io/dinject/SystemContext.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,4 +120,21 @@ public static <T> List<T> getBeans(Class<T> interfaceType) {
120120
return rootContext.getBeans(interfaceType);
121121
}
122122

123+
/**
124+
* Return the list of beans that implement the interface without ordering based on <code>@Priority</code>.
125+
*
126+
* <pre>{@code
127+
*
128+
* // e.g. register all web routes with web a framework
129+
*
130+
* List<WebRoute> routes = SystemContext.getBeansUnsorted(WebRoute.class);
131+
*
132+
* }</pre>
133+
*
134+
* @param interfaceType An interface class.
135+
*/
136+
public static <T> List<T> getBeansUnsorted(Class<T> interfaceType) {
137+
return rootContext.getBeansUnsorted(interfaceType);
138+
}
139+
123140
}

src/main/java/io/dinject/core/DBeanContext.java

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
import org.slf4j.Logger;
66
import org.slf4j.LoggerFactory;
77

8+
import javax.annotation.Priority;
89
import java.util.ArrayList;
10+
import java.util.Collections;
911
import java.util.List;
1012
import java.util.Map;
1113

@@ -76,15 +78,45 @@ public <T> T getBean(Class<T> beanClass, String name) {
7678
}
7779

7880
@Override
79-
public <T> List<T> getBeans(Class<T> interfaceType) {
81+
public <T> List<T> getBeansUnsorted(Class<T> interfaceType) {
8082
List<T> list = new ArrayList<>();
8183
beans.addAll(interfaceType, list);
8284
for (BeanContext childContext : children.values()) {
83-
list.addAll(childContext.getBeans(interfaceType));
85+
list.addAll(childContext.getBeansUnsorted(interfaceType));
8486
}
8587
return list;
8688
}
8789

90+
@Override
91+
public <T> List<T> getBeans(Class<T> interfaceType) {
92+
List<T> list = getBeansUnsorted(interfaceType);
93+
return list.size() > 1 ? sortByPriority(list) : list;
94+
}
95+
96+
@Override
97+
public <T> List<T> sortByPriority(List<T> list) {
98+
boolean priorityUsed = false;
99+
List<SortBean<T>> tempList = new ArrayList<>(list.size());
100+
for (T bean : list) {
101+
SortBean<T> sortBean = new SortBean<>(bean);
102+
tempList.add(sortBean);
103+
if (!priorityUsed && sortBean.priorityDefined) {
104+
priorityUsed = true;
105+
}
106+
}
107+
if (!priorityUsed) {
108+
// nothing with Priority annotation so return original order
109+
return list;
110+
}
111+
Collections.sort(tempList);
112+
// unpack into new sorted list
113+
List<T> sorted = new ArrayList<>(tempList.size());
114+
for (SortBean<T> sortBean : tempList) {
115+
sorted.add(sortBean.bean);
116+
}
117+
return sorted;
118+
}
119+
88120
@Override
89121
public List<Object> getBeansWithAnnotation(Class<?> annotation) {
90122

@@ -186,4 +218,34 @@ BeanEntry<T> get() {
186218
return secondary;
187219
}
188220
}
221+
222+
private static class SortBean<T> implements Comparable<SortBean<T>> {
223+
224+
private final T bean;
225+
226+
private boolean priorityDefined;
227+
228+
private final int priority;
229+
230+
SortBean(T bean) {
231+
this.bean = bean;
232+
this.priority = initPriority();
233+
}
234+
235+
int initPriority() {
236+
final Priority ann = bean.getClass().getAnnotation(Priority.class);
237+
if (ann != null) {
238+
priorityDefined = true;
239+
return ann.value();
240+
}
241+
// Default priority as per javax.ws.rs.Priorities.USER
242+
// User-level filter/interceptor priority
243+
return 5000;
244+
}
245+
246+
@Override
247+
public int compareTo(SortBean<T> o) {
248+
return Integer.compare(priority, o.priority);
249+
}
250+
}
189251
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package io.dinject;
2+
3+
import org.example.coffee.list.ASomei;
4+
import org.example.coffee.list.BSomei;
5+
import org.example.coffee.list.Somei;
6+
import org.junit.Test;
7+
8+
import java.util.List;
9+
10+
import static org.assertj.core.api.Assertions.assertThat;
11+
12+
public class SystemContextTest {
13+
14+
@Test
15+
public void getBeans_withPriority() {
16+
17+
final List<Somei> beans = SystemContext.getBeans(Somei.class);
18+
assertThat(beans).hasSize(2);
19+
20+
assertThat(beans.get(0)).isInstanceOf(BSomei.class);
21+
assertThat(beans.get(1)).isInstanceOf(ASomei.class);
22+
}
23+
24+
@Test
25+
public void getBeansUnsorted_withPriority() {
26+
27+
final List<Somei> beans = SystemContext.getBeansUnsorted(Somei.class);
28+
assertThat(beans).hasSize(2);
29+
30+
assertThat(beans.get(0)).isInstanceOf(ASomei.class);
31+
assertThat(beans.get(1)).isInstanceOf(BSomei.class);
32+
}
33+
}

src/test/java/org/example/coffee/list/ASomei.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package org.example.coffee.list;
22

3+
import javax.annotation.Priority;
34
import javax.inject.Singleton;
45

56
@Singleton
7+
@Priority(2)
68
public class ASomei implements Somei {
79

810
@Override

src/test/java/org/example/coffee/list/BSomei.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package org.example.coffee.list;
22

3+
import javax.annotation.Priority;
34
import javax.inject.Singleton;
45

56
@Singleton
7+
@Priority(1)
68
public class BSomei implements Somei {
79

810
@Override

0 commit comments

Comments
 (0)