Skip to content

Commit 839fb27

Browse files
jansupolsenivam
authored andcommitted
Allow for specifying Feature processing order
Signed-off-by: jansupol <[email protected]>
1 parent e3cc623 commit 839fb27

File tree

2 files changed

+103
-18
lines changed

2 files changed

+103
-18
lines changed

core-common/src/main/java/org/glassfish/jersey/model/internal/CommonConfig.java

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -109,19 +109,34 @@ private static final class FeatureRegistration {
109109
private final Class<? extends Feature> featureClass;
110110
private final Feature feature;
111111
private final RuntimeType runtimeType;
112+
private final int priority;
112113

113-
private FeatureRegistration(final Class<? extends Feature> featureClass) {
114+
private FeatureRegistration(final Class<? extends Feature> featureClass, int priority) {
114115
this.featureClass = featureClass;
115116
this.feature = null;
116117
final ConstrainedTo runtimeTypeConstraint = featureClass.getAnnotation(ConstrainedTo.class);
117118
this.runtimeType = runtimeTypeConstraint == null ? null : runtimeTypeConstraint.value();
119+
this.priority = priority(featureClass, priority);
118120
}
119121

120-
private FeatureRegistration(final Feature feature) {
122+
private FeatureRegistration(final Feature feature, int priority) {
121123
this.featureClass = feature.getClass();
122124
this.feature = feature;
123125
final ConstrainedTo runtimeTypeConstraint = featureClass.getAnnotation(ConstrainedTo.class);
124126
this.runtimeType = runtimeTypeConstraint == null ? null : runtimeTypeConstraint.value();
127+
this.priority = priority(featureClass, priority);
128+
}
129+
130+
private static int priority(Class<? extends Feature> featureClass, int priority) {
131+
if (priority != ContractProvider.NO_PRIORITY) {
132+
return priority;
133+
}
134+
final Priority priorityAnnotation = featureClass.getAnnotation(Priority.class);
135+
if (priorityAnnotation != null) {
136+
return priorityAnnotation.value();
137+
} else {
138+
return Priorities.USER;
139+
}
125140
}
126141

127142
/**
@@ -400,7 +415,7 @@ public CommonConfig property(final String name, final Object value) {
400415
public CommonConfig register(final Class<?> componentClass) {
401416
checkComponentClassNotNull(componentClass);
402417
if (componentBag.register(componentClass, getModelEnhancer(componentClass))) {
403-
processFeatureRegistration(null, componentClass);
418+
processFeatureRegistration(null, componentClass, ContractProvider.NO_PRIORITY);
404419
}
405420

406421
return this;
@@ -410,7 +425,7 @@ public CommonConfig register(final Class<?> componentClass) {
410425
public CommonConfig register(final Class<?> componentClass, final int bindingPriority) {
411426
checkComponentClassNotNull(componentClass);
412427
if (componentBag.register(componentClass, bindingPriority, getModelEnhancer(componentClass))) {
413-
processFeatureRegistration(null, componentClass);
428+
processFeatureRegistration(null, componentClass, bindingPriority);
414429
}
415430

416431
return this;
@@ -424,7 +439,7 @@ public CommonConfig register(final Class<?> componentClass, final Class<?>... co
424439
return this;
425440
}
426441
if (componentBag.register(componentClass, asNewIdentitySet(contracts), getModelEnhancer(componentClass))) {
427-
processFeatureRegistration(null, componentClass);
442+
processFeatureRegistration(null, componentClass, ContractProvider.NO_PRIORITY);
428443
}
429444

430445
return this;
@@ -434,7 +449,7 @@ public CommonConfig register(final Class<?> componentClass, final Class<?>... co
434449
public CommonConfig register(final Class<?> componentClass, final Map<Class<?>, Integer> contracts) {
435450
checkComponentClassNotNull(componentClass);
436451
if (componentBag.register(componentClass, contracts, getModelEnhancer(componentClass))) {
437-
processFeatureRegistration(null, componentClass);
452+
processFeatureRegistration(null, componentClass, ContractProvider.NO_PRIORITY);
438453
}
439454

440455
return this;
@@ -446,7 +461,7 @@ public CommonConfig register(final Object component) {
446461

447462
final Class<?> componentClass = component.getClass();
448463
if (componentBag.register(component, getModelEnhancer(componentClass))) {
449-
processFeatureRegistration(component, componentClass);
464+
processFeatureRegistration(component, componentClass, ContractProvider.NO_PRIORITY);
450465
}
451466

452467
return this;
@@ -457,7 +472,7 @@ public CommonConfig register(final Object component, final int bindingPriority)
457472
checkProviderNotNull(component);
458473
final Class<?> componentClass = component.getClass();
459474
if (componentBag.register(component, bindingPriority, getModelEnhancer(componentClass))) {
460-
processFeatureRegistration(component, componentClass);
475+
processFeatureRegistration(component, componentClass, bindingPriority);
461476
}
462477

463478
return this;
@@ -472,7 +487,7 @@ public CommonConfig register(final Object component, final Class<?>... contracts
472487
return this;
473488
}
474489
if (componentBag.register(component, asNewIdentitySet(contracts), getModelEnhancer(componentClass))) {
475-
processFeatureRegistration(component, componentClass);
490+
processFeatureRegistration(component, componentClass, ContractProvider.NO_PRIORITY);
476491
}
477492

478493
return this;
@@ -483,19 +498,19 @@ public CommonConfig register(final Object component, final Map<Class<?>, Integer
483498
checkProviderNotNull(component);
484499
final Class<?> componentClass = component.getClass();
485500
if (componentBag.register(component, contracts, getModelEnhancer(componentClass))) {
486-
processFeatureRegistration(component, componentClass);
501+
processFeatureRegistration(component, componentClass, ContractProvider.NO_PRIORITY);
487502
}
488503

489504
return this;
490505
}
491506

492-
private void processFeatureRegistration(final Object component, final Class<?> componentClass) {
507+
private void processFeatureRegistration(final Object component, final Class<?> componentClass, int priority) {
493508
final ContractProvider model = componentBag.getModel(componentClass);
494509
if (model.getContracts().contains(Feature.class)) {
495510
@SuppressWarnings("unchecked")
496511
final FeatureRegistration registration = (component != null)
497-
? new FeatureRegistration((Feature) component)
498-
: new FeatureRegistration((Class<? extends Feature>) componentClass);
512+
? new FeatureRegistration((Feature) component, priority)
513+
: new FeatureRegistration((Class<? extends Feature>) componentClass, priority);
499514
newFeatureRegistrations.add(registration);
500515
}
501516
}
@@ -524,7 +539,7 @@ public CommonConfig loadFrom(final Configuration config) {
524539
this.enabledFeatureClasses.clear();
525540

526541
componentBag.clear();
527-
resetRegistrations();
542+
resetFeatureRegistrations();
528543

529544
for (final Class<?> clazz : config.getClasses()) {
530545
if (Feature.class.isAssignableFrom(clazz) && config.isEnabled((Class<? extends Feature>) clazz)) {
@@ -629,7 +644,7 @@ public void configureMetaProviders(InjectionManager injectionManager, ManagedObj
629644
// Next, register external meta objects
630645
configureExternalObjects(injectionManager, configuredExternals);
631646
// Configure all features
632-
configureFeatures(injectionManager, new HashSet<>(), resetRegistrations(), finalizer);
647+
configureFeatures(injectionManager, new HashSet<>(), resetFeatureRegistrations(), finalizer);
633648
// Next, register external meta objects registered by features
634649
configureExternalObjects(injectionManager, configuredExternals);
635650
// At last, configure any new binders added by features
@@ -718,16 +733,17 @@ private void configureFeatures(InjectionManager injectionManager,
718733
if (providerModel != null) {
719734
ProviderBinder.bindProvider(feature, providerModel, injectionManager);
720735
}
721-
configureFeatures(injectionManager, processed, resetRegistrations(), managedObjectsFinalizer);
736+
configureFeatures(injectionManager, processed, resetFeatureRegistrations(), managedObjectsFinalizer);
722737
enabledFeatureClasses.add(registration.getFeatureClass());
723738
enabledFeatures.add(feature);
724739
}
725740
}
726741
}
727742

728-
private List<FeatureRegistration> resetRegistrations() {
743+
private List<FeatureRegistration> resetFeatureRegistrations() {
729744
final List<FeatureRegistration> result = new ArrayList<>(newFeatureRegistrations);
730745
newFeatureRegistrations.clear();
746+
Collections.sort(result, (o1, o2) -> o1.priority < o2.priority ? -1 : 1);
731747
return result;
732748
}
733749

tests/e2e-core-common/src/test/java/org/glassfish/jersey/tests/e2e/common/model/internal/CommonConfigTest.java

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
33
*
44
* This program and the accompanying materials are made available under the
55
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -57,6 +57,7 @@
5757
import org.junit.Ignore;
5858
import org.junit.Test;
5959
import static org.hamcrest.CoreMatchers.is;
60+
import static org.hamcrest.Matchers.lessThan;
6061
import static org.junit.Assert.assertEquals;
6162
import static org.junit.Assert.assertFalse;
6263
import static org.junit.Assert.assertNotNull;
@@ -997,4 +998,72 @@ public void testFeatureInjectionsBindInFeature() throws Exception {
997998
assertThat("Feature class not injected", config.getProperty("class-injected").toString(), is("true"));
998999
}
9991000

1001+
// ===========================================================================================================================
1002+
1003+
@Test
1004+
public void testFeatureBindingPriority() {
1005+
final InjectionManager injectionManager = Injections.createInjectionManager();
1006+
final ManagedObjectsFinalizer finalizer = new ManagedObjectsFinalizer(injectionManager);
1007+
config.register(new OrderedFeature(Priorities.USER){}, Priorities.USER);
1008+
config.register(new OrderedFeature(Priorities.USER - 100){}, Priorities.USER - 100);
1009+
config.register(new OrderedFeature(Priorities.USER + 100){}, Priorities.USER + 100);
1010+
config.configureMetaProviders(injectionManager, finalizer);
1011+
int value = (int) config.getProperty(OrderedFeature.PROPERTY_NAME);
1012+
1013+
assertEquals(Priorities.USER + 100, value);
1014+
}
1015+
1016+
private static class OrderedFeature implements Feature {
1017+
private final int orderId;
1018+
private static final String PROPERTY_NAME = "ORDER_ID";
1019+
1020+
private OrderedFeature(int orderId) {
1021+
this.orderId = orderId;
1022+
}
1023+
1024+
@Override
1025+
public boolean configure(FeatureContext context) {
1026+
Integer previousId = (Integer) context.getConfiguration().getProperty(PROPERTY_NAME);
1027+
if (previousId != null) {
1028+
assertThat(previousId, lessThan(orderId));
1029+
}
1030+
context.property(PROPERTY_NAME, orderId);
1031+
return false;
1032+
}
1033+
}
1034+
1035+
@Test
1036+
public void testFeatureAnnotatedPriority() {
1037+
final InjectionManager injectionManager = Injections.createInjectionManager();
1038+
final ManagedObjectsFinalizer finalizer = new ManagedObjectsFinalizer(injectionManager);
1039+
config.register(PriorityFeature1.class);
1040+
config.register(PriorityFeature2.class);
1041+
config.register(PriorityFeature3.class);
1042+
config.configureMetaProviders(injectionManager, finalizer);
1043+
int value = (int) config.getProperty(OrderedFeature.PROPERTY_NAME);
1044+
1045+
assertEquals(Priorities.USER + 100, value);
1046+
}
1047+
1048+
@Priority(Priorities.USER)
1049+
private static class PriorityFeature1 extends OrderedFeature {
1050+
private PriorityFeature1() {
1051+
super(Priorities.USER);
1052+
}
1053+
}
1054+
1055+
@Priority(Priorities.USER - 100)
1056+
private static class PriorityFeature2 extends OrderedFeature {
1057+
private PriorityFeature2() {
1058+
super(Priorities.USER - 100);
1059+
}
1060+
}
1061+
1062+
@Priority(Priorities.USER + 100)
1063+
private static class PriorityFeature3 extends OrderedFeature {
1064+
private PriorityFeature3() {
1065+
super(Priorities.USER + 100);
1066+
}
1067+
}
1068+
10001069
}

0 commit comments

Comments
 (0)