4343import java .util .Arrays ;
4444import java .util .Collection ;
4545import java .util .Collections ;
46+ import java .util .Comparator ;
4647import java .util .HashMap ;
4748import java .util .HashSet ;
4849import java .util .LinkedList ;
4950import java .util .List ;
5051import java .util .Map ;
5152import java .util .Set ;
53+ import java .util .TreeSet ;
5254import java .util .logging .Level ;
5355import java .util .logging .Logger ;
5456
5557import javax .ws .rs .ConstrainedTo ;
58+ import javax .ws .rs .Priorities ;
5659import javax .ws .rs .RuntimeType ;
5760import javax .ws .rs .core .Configuration ;
5861import javax .ws .rs .core .Feature ;
5962import javax .ws .rs .core .FeatureContext ;
6063
64+ import javax .annotation .Priority ;
65+
6166import org .glassfish .jersey .ExtendedConfig ;
6267import org .glassfish .jersey .internal .LocalizationMessages ;
68+ import org .glassfish .jersey .internal .ServiceFinder ;
6369import org .glassfish .jersey .internal .inject .Injections ;
6470import org .glassfish .jersey .internal .inject .Providers ;
6571import org .glassfish .jersey .internal .spi .AutoDiscoverable ;
72+ import org .glassfish .jersey .internal .spi .ForcedAutoDiscoverable ;
6673import org .glassfish .jersey .internal .util .PropertiesHelper ;
6774import org .glassfish .jersey .model .ContractProvider ;
6875import org .glassfish .jersey .process .Inflector ;
@@ -88,7 +95,7 @@ public class CommonConfig implements FeatureContext, ExtendedConfig {
8895 private static final Logger LOGGER = Logger .getLogger (CommonConfig .class .getName ());
8996 private static final Function <Object , Binder > CAST_TO_BINDER = new Function <Object , Binder >() {
9097 @ Override
91- public Binder apply (Object input ) {
98+ public Binder apply (final Object input ) {
9299 return Binder .class .cast (input );
93100 }
94101 };
@@ -171,7 +178,7 @@ public boolean equals(final Object obj) {
171178 if (!(obj instanceof FeatureRegistration )) {
172179 return false ;
173180 }
174- FeatureRegistration other = (FeatureRegistration ) obj ;
181+ final FeatureRegistration other = (FeatureRegistration ) obj ;
175182
176183 return (featureClass == other .featureClass )
177184 || (feature != null && (feature == other .feature || feature .equals (other .feature )));
@@ -206,7 +213,7 @@ public int hashCode() {
206213 * or not should the component class registration continue
207214 * towards a successful completion.
208215 */
209- public CommonConfig (RuntimeType type , Predicate <ContractProvider > registrationStrategy ) {
216+ public CommonConfig (final RuntimeType type , final Predicate <ContractProvider > registrationStrategy ) {
210217 this .type = type ;
211218
212219 this .properties = new HashMap <String , Object >();
@@ -291,7 +298,7 @@ public Object getProperty(final String name) {
291298 }
292299
293300 @ Override
294- public boolean isProperty (String name ) {
301+ public boolean isProperty (final String name ) {
295302 return PropertiesHelper .isProperty (getProperty (name ));
296303 }
297304
@@ -311,17 +318,17 @@ public boolean isEnabled(final Feature feature) {
311318 }
312319
313320 @ Override
314- public boolean isRegistered (Object component ) {
321+ public boolean isRegistered (final Object component ) {
315322 return componentBag .getInstances ().contains (component );
316323 }
317324
318325 @ Override
319- public boolean isRegistered (Class <?> componentClass ) {
326+ public boolean isRegistered (final Class <?> componentClass ) {
320327 return componentBag .getRegistrations ().contains (componentClass );
321328 }
322329
323330 @ Override
324- public Map <Class <?>, Integer > getContracts (Class <?> componentClass ) {
331+ public Map <Class <?>, Integer > getContracts (final Class <?> componentClass ) {
325332 final ContractProvider model = componentBag .getModel (componentClass );
326333 return (model == null ) ? Collections .<Class <?>, Integer >emptyMap () : model .getContractMap ();
327334 }
@@ -439,7 +446,7 @@ public CommonConfig register(final Class<?> componentClass, final Class<?>... co
439446 }
440447
441448 @ Override
442- public CommonConfig register (final Class <?> componentClass , Map <Class <?>, Integer > contracts ) {
449+ public CommonConfig register (final Class <?> componentClass , final Map <Class <?>, Integer > contracts ) {
443450 checkComponentClassNotNull (componentClass );
444451 if (componentBag .register (componentClass , contracts , getModelEnhancer (componentClass ))) {
445452 processFeatureRegistration (null , componentClass );
@@ -487,7 +494,7 @@ public CommonConfig register(final Object component, final Class<?>... contracts
487494 }
488495
489496 @ Override
490- public CommonConfig register (final Object component , Map <Class <?>, Integer > contracts ) {
497+ public CommonConfig register (final Object component , final Map <Class <?>, Integer > contracts ) {
491498 checkProviderNotNull (component );
492499 final Class <?> componentClass = component .getClass ();
493500 if (componentBag .register (component , contracts , getModelEnhancer (componentClass ))) {
@@ -497,8 +504,8 @@ public CommonConfig register(final Object component, Map<Class<?>, Integer> cont
497504 return this ;
498505 }
499506
500- private void processFeatureRegistration (Object component , Class <?> componentClass ) {
501- ContractProvider model = componentBag .getModel (componentClass );
507+ private void processFeatureRegistration (final Object component , final Class <?> componentClass ) {
508+ final ContractProvider model = componentBag .getModel (componentClass );
502509 if (model .getContracts ().contains (Feature .class )) {
503510 @ SuppressWarnings ("unchecked" )
504511 final FeatureRegistration registration = (component != null ) ?
@@ -518,7 +525,7 @@ private void processFeatureRegistration(Object component, Class<?> componentClas
518525 * @param config external configuration state to replace the configuration of this configurable instance.
519526 * @return the updated common configuration instance.
520527 */
521- public CommonConfig loadFrom (Configuration config ) {
528+ public CommonConfig loadFrom (final Configuration config ) {
522529 if (config instanceof CommonConfig ) {
523530 // If loading from CommonConfig then simply copy properties and check whether given config has been initialized.
524531 final CommonConfig commonConfig = (CommonConfig ) config ;
@@ -554,19 +561,19 @@ public CommonConfig loadFrom(Configuration config) {
554561 return this ;
555562 }
556563
557- private Set <Class <?>> asNewIdentitySet (Class <?>... contracts ) {
558- Set <Class <?>> result = Sets .newIdentityHashSet ();
564+ private Set <Class <?>> asNewIdentitySet (final Class <?>... contracts ) {
565+ final Set <Class <?>> result = Sets .newIdentityHashSet ();
559566 result .addAll (Arrays .asList (contracts ));
560567 return result ;
561568 }
562569
563- private void checkProviderNotNull (Object provider ) {
570+ private void checkProviderNotNull (final Object provider ) {
564571 if (provider == null ) {
565572 throw new IllegalArgumentException (LocalizationMessages .COMPONENT_CANNOT_BE_NULL ());
566573 }
567574 }
568575
569- private void checkComponentClassNotNull (Class <?> componentClass ) {
576+ private void checkComponentClassNotNull (final Class <?> componentClass ) {
570577 if (componentClass == null ) {
571578 throw new IllegalArgumentException (LocalizationMessages .COMPONENT_CLASS_CANNOT_BE_NULL ());
572579 }
@@ -576,17 +583,40 @@ private void checkComponentClassNotNull(Class<?> componentClass) {
576583 * Configure {@link AutoDiscoverable auto-discoverables} in the HK2 service locator.
577584 *
578585 * @param locator locator in which the auto-discoverables should be configured.
586+ * @param forcedOnly defines whether all or only forced auto-discoverables should be configured.
579587 */
580- public void configureAutoDiscoverableProviders (final ServiceLocator locator ) {
588+ public void configureAutoDiscoverableProviders (final ServiceLocator locator , final boolean forcedOnly ) {
581589 // Check whether meta providers have been initialized for a config this config has been loaded from.
582590 if (!disableMetaProviderConfiguration ) {
583- for (final AutoDiscoverable autoDiscoverable : Providers .getProviders (locator , AutoDiscoverable .class )) {
591+ final Set <AutoDiscoverable > providers = new TreeSet <AutoDiscoverable >(new Comparator <AutoDiscoverable >() {
592+ @ Override
593+ public int compare (final AutoDiscoverable o1 , final AutoDiscoverable o2 ) {
594+ final int p1 = o1 .getClass ().isAnnotationPresent (Priority .class )
595+ ? o1 .getClass ().getAnnotation (Priority .class ).value () : Priorities .USER ;
596+ final int p2 = o2 .getClass ().isAnnotationPresent (Priority .class )
597+ ? o2 .getClass ().getAnnotation (Priority .class ).value () : Priorities .USER ;
598+
599+ final int compare = Integer .compare (p1 , p2 );
600+ return compare == 0 ? -1 : compare ;
601+ }
602+ });
603+
604+ // Forced (always invoked).
605+ providers .addAll (Arrays .asList (
606+ ServiceFinder .find (ForcedAutoDiscoverable .class , true ).toArray ()));
607+
608+ // Regular.
609+ if (!forcedOnly ) {
610+ providers .addAll (Providers .getProviders (locator , AutoDiscoverable .class ));
611+ }
612+
613+ for (final AutoDiscoverable autoDiscoverable : providers ) {
584614 final ConstrainedTo constrainedTo = autoDiscoverable .getClass ().getAnnotation (ConstrainedTo .class );
585615
586616 if (constrainedTo == null || type .equals (constrainedTo .value ())) {
587617 try {
588618 autoDiscoverable .configure (this );
589- } catch (Exception e ) {
619+ } catch (final Exception e ) {
590620 LOGGER .log (Level .FINE ,
591621 LocalizationMessages .AUTODISCOVERABLE_CONFIGURATION_FAILED (autoDiscoverable .getClass ()), e );
592622 }
@@ -618,14 +648,14 @@ public void configureMetaProviders(final ServiceLocator locator) {
618648 }
619649
620650 private Set <Binder > configureBinders (final ServiceLocator locator , final Set <Binder > configured ) {
621- Set <Binder > allConfigured = Sets .newIdentityHashSet ();
651+ final Set <Binder > allConfigured = Sets .newIdentityHashSet ();
622652 allConfigured .addAll (configured );
623653
624654 final Collection <Binder > binders = getBinders (configured );
625655 if (!binders .isEmpty ()) {
626656 final DynamicConfiguration dc = Injections .getConfiguration (locator );
627657
628- for (Binder binder : binders ) {
658+ for (final Binder binder : binders ) {
629659 binder .bind (dc );
630660 allConfigured .add (binder );
631661 }
@@ -640,7 +670,7 @@ private Collection<Binder> getBinders(final Set<Binder> configured) {
640670 Collections2 .transform (componentBag .getInstances (ComponentBag .BINDERS_ONLY ), CAST_TO_BINDER ),
641671 new Predicate <Binder >() {
642672 @ Override
643- public boolean apply (Binder binder ) {
673+ public boolean apply (final Binder binder ) {
644674 return !configured .contains (binder );
645675 }
646676 });
@@ -651,7 +681,7 @@ private void configureFeatures(final ServiceLocator locator,
651681 final List <FeatureRegistration > unprocessed ) {
652682
653683 FeatureContextWrapper featureContextWrapper = null ;
654- for (FeatureRegistration registration : unprocessed ) {
684+ for (final FeatureRegistration registration : unprocessed ) {
655685 if (processed .contains (registration )) {
656686 LOGGER .config (LocalizationMessages .FEATURE_HAS_ALREADY_BEEN_PROCESSED (registration .getFeatureClass ()));
657687 continue ;
@@ -677,7 +707,7 @@ private void configureFeatures(final ServiceLocator locator,
677707 // init lazily
678708 featureContextWrapper = new FeatureContextWrapper (this , locator );
679709 }
680- boolean success = feature .configure (featureContextWrapper );
710+ final boolean success = feature .configure (featureContextWrapper );
681711
682712 if (success ) {
683713 processed .add (registration );
@@ -691,21 +721,21 @@ private void configureFeatures(final ServiceLocator locator,
691721 }
692722
693723 private List <FeatureRegistration > resetRegistrations () {
694- List <FeatureRegistration > result = new ArrayList <FeatureRegistration >(newFeatureRegistrations );
724+ final List <FeatureRegistration > result = new ArrayList <FeatureRegistration >(newFeatureRegistrations );
695725 newFeatureRegistrations .clear ();
696726 return result ;
697727 }
698728
699729 @ Override
700- public boolean equals (Object o ) {
730+ public boolean equals (final Object o ) {
701731 if (this == o ) {
702732 return true ;
703733 }
704734 if (!(o instanceof CommonConfig )) {
705735 return false ;
706736 }
707737
708- CommonConfig that = (CommonConfig ) o ;
738+ final CommonConfig that = (CommonConfig ) o ;
709739
710740 if (type != that .type ) {
711741 return false ;
0 commit comments