< prev index next >

src/java.base/share/classes/java/util/ServiceLoader.java

Print this page




 990             next = null;
 991 
 992             // attempt to load provider
 993             Module module = provider.module();
 994             String cn = provider.providerName();
 995             Class<?> clazz = loadProviderInModule(module, cn);
 996             return new ProviderImpl<T>(service, clazz, acc);
 997         }
 998     }
 999 
1000     /**
1001      * Implements lazy service provider lookup where the service providers are
1002      * configured via service configuration files. Service providers in named
1003      * modules are silently ignored by this lookup iterator.
1004      */
1005     private final class LazyClassPathLookupIterator<T>
1006         implements Iterator<Provider<T>>
1007     {
1008         static final String PREFIX = "META-INF/services/";
1009 

1010         Enumeration<URL> configs;
1011         Iterator<String> pending;
1012         Class<?> nextClass;
1013         String nextErrorMessage;  // when hasNext fails with CNFE
1014 
1015         LazyClassPathLookupIterator() { }
1016 
1017         /**
1018          * Parse a single line from the given configuration file, adding the
1019          * name on the line to the names list.
1020          */
1021         private int parseLine(URL u, BufferedReader r, int lc, Set<String> names)
1022             throws IOException
1023         {
1024             String ln = r.readLine();
1025             if (ln == null) {
1026                 return -1;
1027             }
1028             int ci = ln.indexOf('#');
1029             if (ci >= 0) ln = ln.substring(0, ci);
1030             ln = ln.trim();
1031             int n = ln.length();
1032             if (n != 0) {
1033                 if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0))
1034                     fail(service, u, lc, "Illegal configuration-file syntax");
1035                 int cp = ln.codePointAt(0);
1036                 if (!Character.isJavaIdentifierStart(cp))
1037                     fail(service, u, lc, "Illegal provider-class name: " + ln);
1038                 int start = Character.charCount(cp);
1039                 for (int i = start; i < n; i += Character.charCount(cp)) {
1040                     cp = ln.codePointAt(i);
1041                     if (!Character.isJavaIdentifierPart(cp) && (cp != '.'))
1042                         fail(service, u, lc, "Illegal provider-class name: " + ln);
1043                 }

1044                 names.add(ln);
1045             }

1046             return lc + 1;
1047         }
1048 
1049         /**
1050          * Parse the content of the given URL as a provider-configuration file.
1051          */
1052         private Iterator<String> parse(URL u) {
1053             Set<String> names = new LinkedHashSet<>(); // preserve insertion order
1054             try {
1055                 URLConnection uc = u.openConnection();
1056                 uc.setUseCaches(false);
1057                 try (InputStream in = uc.getInputStream();
1058                      BufferedReader r
1059                          = new BufferedReader(new InputStreamReader(in, "utf-8")))
1060                 {
1061                     int lc = 1;
1062                     while ((lc = parseLine(u, r, lc, names)) >= 0);
1063                 }
1064             } catch (IOException x) {
1065                 fail(service, "Error accessing configuration file", x);
1066             }
1067             return names.iterator();
1068         }
1069 
1070         private boolean hasNextService() {
1071             if (nextClass != null || nextErrorMessage != null) {
1072                 return true;
1073             }
1074 
1075             Class<?> clazz = null;
1076             do {
1077                 if (configs == null) {
1078                     try {
1079                         String fullName = PREFIX + service.getName();
1080                         if (loader == null) {
1081                             configs = ClassLoader.getSystemResources(fullName);
1082                         } else if (loader == ClassLoaders.platformClassLoader()) {
1083                             // The platform classloader doesn't have a class path,
1084                             // but the boot loader might.
1085                             if (BootLoader.hasClassPath()) {
1086                                 configs = BootLoader.findResources(fullName);
1087                             } else {
1088                                 configs = Collections.emptyEnumeration();
1089                             }
1090                         } else {
1091                             configs = loader.getResources(fullName);
1092                         }
1093                     } catch (IOException x) {
1094                         fail(service, "Error locating configuration files", x);
1095                     }




 990             next = null;
 991 
 992             // attempt to load provider
 993             Module module = provider.module();
 994             String cn = provider.providerName();
 995             Class<?> clazz = loadProviderInModule(module, cn);
 996             return new ProviderImpl<T>(service, clazz, acc);
 997         }
 998     }
 999 
1000     /**
1001      * Implements lazy service provider lookup where the service providers are
1002      * configured via service configuration files. Service providers in named
1003      * modules are silently ignored by this lookup iterator.
1004      */
1005     private final class LazyClassPathLookupIterator<T>
1006         implements Iterator<Provider<T>>
1007     {
1008         static final String PREFIX = "META-INF/services/";
1009 
1010         Set<String> providerNames = new HashSet<>();  // to avoid duplicates
1011         Enumeration<URL> configs;
1012         Iterator<String> pending;
1013         Class<?> nextClass;
1014         String nextErrorMessage;  // when hasNext fails with CNFE
1015 
1016         LazyClassPathLookupIterator() { }
1017 
1018         /**
1019          * Parse a single line from the given configuration file, adding the
1020          * name on the line to set of names if not already seen.
1021          */
1022         private int parseLine(URL u, BufferedReader r, int lc, Set<String> names)
1023             throws IOException
1024         {
1025             String ln = r.readLine();
1026             if (ln == null) {
1027                 return -1;
1028             }
1029             int ci = ln.indexOf('#');
1030             if (ci >= 0) ln = ln.substring(0, ci);
1031             ln = ln.trim();
1032             int n = ln.length();
1033             if (n != 0) {
1034                 if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0))
1035                     fail(service, u, lc, "Illegal configuration-file syntax");
1036                 int cp = ln.codePointAt(0);
1037                 if (!Character.isJavaIdentifierStart(cp))
1038                     fail(service, u, lc, "Illegal provider-class name: " + ln);
1039                 int start = Character.charCount(cp);
1040                 for (int i = start; i < n; i += Character.charCount(cp)) {
1041                     cp = ln.codePointAt(i);
1042                     if (!Character.isJavaIdentifierPart(cp) && (cp != '.'))
1043                         fail(service, u, lc, "Illegal provider-class name: " + ln);
1044                 }
1045                 if (providerNames.add(ln)) {
1046                     names.add(ln);
1047                 }
1048             }
1049             return lc + 1;
1050         }
1051 
1052         /**
1053          * Parse the content of the given URL as a provider-configuration file.
1054          */
1055         private Iterator<String> parse(URL u) {
1056             Set<String> names = new LinkedHashSet<>(); // preserve insertion order
1057             try {
1058                 URLConnection uc = u.openConnection();
1059                 uc.setUseCaches(false);
1060                 try (InputStream in = uc.getInputStream();
1061                      BufferedReader r
1062                          = new BufferedReader(new InputStreamReader(in, "utf-8")))
1063                 {
1064                     int lc = 1;
1065                     while ((lc = parseLine(u, r, lc, names)) >= 0);
1066                 }
1067             } catch (IOException x) {
1068                 fail(service, "Error accessing configuration file", x);
1069             }
1070             return names.iterator();
1071         }
1072 
1073         private boolean hasNextService() {
1074             if (nextClass != null || nextErrorMessage != null) {
1075                 return true;
1076             }
1077 
1078             Class<?> clazz;
1079             do {
1080                 if (configs == null) {
1081                     try {
1082                         String fullName = PREFIX + service.getName();
1083                         if (loader == null) {
1084                             configs = ClassLoader.getSystemResources(fullName);
1085                         } else if (loader == ClassLoaders.platformClassLoader()) {
1086                             // The platform classloader doesn't have a class path,
1087                             // but the boot loader might.
1088                             if (BootLoader.hasClassPath()) {
1089                                 configs = BootLoader.findResources(fullName);
1090                             } else {
1091                                 configs = Collections.emptyEnumeration();
1092                             }
1093                         } else {
1094                             configs = loader.getResources(fullName);
1095                         }
1096                     } catch (IOException x) {
1097                         fail(service, "Error locating configuration files", x);
1098                     }


< prev index next >