11/* 
2-  * Copyright (c) 2010, 2018  Oracle and/or its affiliates. All rights reserved. 
2+  * Copyright (c) 2010, 2022  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 
3131import  java .util .Iterator ;
3232import  java .util .List ;
3333import  java .util .NoSuchElementException ;
34+ import  java .util .ServiceLoader ;
3435import  java .util .Set ;
3536import  java .util .TreeSet ;
3637import  java .util .logging .Level ;
3738import  java .util .logging .Logger ;
39+ import  java .util .stream .Collectors ;
3840
3941import  org .glassfish .jersey .internal .util .ReflectionHelper ;
4042
@@ -229,7 +231,9 @@ public static <T> ServiceFinder<T> find(final Class<T> service, final ClassLoade
229231     *                class loader (or, failing that the bootstrap class loader) is to 
230232     *                be used 
231233     * @param ignoreOnClassNotFound If a provider cannot be loaded by the class loader 
232-      *                              then move on to the next available provider. 
234+      *                              then move on to the next available provider. This value does 
235+      *                              not apply when the {@link ServiceIteratorProvider} is set to 
236+      *                              {@link ServiceLookupIteratorProvider}. 
233237     * @throws ServiceConfigurationError If a provider-configuration file violates the specified format 
234238     *                                   or names a provider class that cannot be found and instantiated 
235239     * @see #find(Class) 
@@ -279,7 +283,10 @@ public static <T> ServiceFinder<T> find(final Class<T> service)
279283     * </pre> 
280284     * @param service The service's abstract service class 
281285     * @param ignoreOnClassNotFound If a provider cannot be loaded by the class loader 
282-      *                              then move on to the next available provider. 
286+      *                              then move on to the next available provider. This value does 
287+      *                              not apply when the {@link ServiceIteratorProvider} is set to 
288+      *                              {@link ServiceLookupIteratorProvider}. 
289+      * 
283290     * @throws ServiceConfigurationError If a provider-configuration file violates the specified format 
284291     *                                   or names a provider class that cannot be found and instantiated 
285292     * @see #find(Class, ClassLoader) 
@@ -312,7 +319,7 @@ public static ServiceFinder<?> find(final String serviceName) throws ServiceConf
312319     * Register the service iterator provider to iterate on provider instances 
313320     * or classes. 
314321     * <p> 
315-      * The default implementation registered, {@link DefaultServiceIteratorProvider }, 
322+      * The default implementation registered, {@link ServiceLookupIteratorProvider }, 
316323     * looks up provider classes in META-INF/service files. 
317324     * <p> 
318325     * This method must be called prior to any attempts to obtain provider 
@@ -790,7 +797,7 @@ private void handleClassNotFoundException() throws ServiceConfigurationError {
790797     * Supports iteration of provider instances or classes. 
791798     * <p> 
792799     * The default implementation looks up provider classes from META-INF/services 
793-      * files, see {@link DefaultServiceIteratorProvider }. 
800+      * files, see {@link ServiceLookupIteratorProvider }. 
794801     * This implementation may be overridden by invoking 
795802     * {@link ServiceFinder#setIteratorProvider(org.glassfish.jersey.internal.ServiceFinder.ServiceIteratorProvider)}. 
796803     */ 
@@ -806,7 +813,7 @@ private static ServiceIteratorProvider getInstance() {
806813                synchronized  (sipLock ) {
807814                    result  = sip ;
808815                    if  (result  == null ) { // Second check (with locking) 
809-                         sip  = result  = new  DefaultServiceIteratorProvider ();
816+                         sip  = result  = new  ServiceLookupIteratorProvider ();
810817                    }
811818                }
812819            }
@@ -834,7 +841,9 @@ private static void setInstance(final ServiceIteratorProvider sip) throws Securi
834841         *        classes. 
835842         * @param ignoreOnClassNotFound if true ignore an instance if the 
836843         *        corresponding provider class if cannot be found, 
837-          *        otherwise throw a {@link ClassNotFoundException}. 
844+          *        otherwise throw a {@link ClassNotFoundException}. This value does 
845+          *        not apply when the {@link ServiceIteratorProvider} is set to 
846+          *        {@link ServiceLookupIteratorProvider}. 
838847         * @return the provider instance iterator. 
839848         */ 
840849        public  abstract  <T > Iterator <T > createIterator (Class <T > service ,
@@ -851,6 +860,8 @@ public abstract <T> Iterator<T> createIterator(Class<T> service,
851860         * @param ignoreOnClassNotFound if true ignore the provider class if 
852861         *        cannot be found, 
853862         *        otherwise throw a {@link ClassNotFoundException}. 
863+          *        This value does not apply when the {@link ServiceIteratorProvider} 
864+          *        is set to {@link ServiceLookupIteratorProvider}. 
854865         * @return the provider class iterator. 
855866         */ 
856867        public  abstract  <T > Iterator <Class <T >> createClassIterator (Class <T > service ,
@@ -860,13 +871,10 @@ public abstract <T> Iterator<Class<T>> createClassIterator(Class<T> service,
860871    }
861872
862873    /** 
863-      * The default  service iterator provider that looks up provider classes in 
874+      * The service iterator provider that looks up provider classes in 
864875     * META-INF/services files. 
865-      * <p> 
866-      * This class may utilized if a {@link ServiceIteratorProvider} needs to 
867-      * reuse the default implementation. 
868876     */ 
869-     public  static  final  class  DefaultServiceIteratorProvider  extends  ServiceIteratorProvider  {
877+     public  static  final  class  ServiceReflectionIteratorProvider  extends  ServiceIteratorProvider  {
870878
871879        @ Override 
872880        public  <T > Iterator <T > createIterator (final  Class <T > service , final  String  serviceName ,
@@ -880,4 +888,41 @@ public <T> Iterator<Class<T>> createClassIterator(final Class<T> service, final
880888            return  new  LazyClassIterator <T >(service , serviceName , loader , ignoreOnClassNotFound );
881889        }
882890    }
891+ 
892+     /** 
893+      * The service iterator provider that looks up provider classes in 
894+      * META-INF/services files using {@link ServiceLoader}. 
895+      */ 
896+     public  static  final  class  ServiceLookupIteratorProvider  extends  ServiceIteratorProvider  {
897+ 
898+         @ Override 
899+         public  <T > Iterator <T > createIterator (final  Class <T > service , final  String  serviceName ,
900+                                               final  ClassLoader  loader , final  boolean  ignoreOnClassNotFound ) {
901+             Class <T > clazz  = fixGenericService (service , serviceName , loader , ignoreOnClassNotFound );
902+             return  ServiceLoader .load (clazz , loader ).iterator ();
903+         }
904+ 
905+         @ Override 
906+         public  <T > Iterator <Class <T >> createClassIterator (final  Class <T > service , final  String  serviceName ,
907+                                                           final  ClassLoader  loader , final  boolean  ignoreOnClassNotFound ) {
908+             Class <T > clazz  = fixGenericService (service , serviceName , loader , ignoreOnClassNotFound );
909+             List <Class <T >> classes  = ServiceLoader .load (clazz , loader ).stream ()
910+                     .map (provider  -> (Class <T >) provider .type ())
911+                     .collect (Collectors .toList ());
912+             return  classes .iterator ();
913+         }
914+ 
915+         private  <T > Class <T > fixGenericService (final  Class <T > service , final  String  serviceName ,
916+                 final  ClassLoader  loader , final  boolean  ignoreOnClassNotFound ) {
917+             Class <T > clazz  = service ;
918+             if  (Object .class  == service ) {
919+                 try  {
920+                     clazz  = (Class <T >) ReflectionHelper .classForNameWithExceptionPEA (serviceName , loader ).run ();
921+                 } catch  (Exception  e ) {
922+                     // Ignore it. Later, the service implementation will not be loaded. 
923+                 }
924+             }
925+             return  clazz ;
926+         }
927+     }
883928}
0 commit comments