1 package org.apache.maven.plugin.surefire.booterclient;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 import java.io.BufferedReader;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.InputStreamReader;
26 import java.net.URL;
27 import java.util.Collections;
28 import java.util.Enumeration;
29 import java.util.HashSet;
30 import java.util.Set;
31
32 /**
33 * @author Stephen Conolly
34 * @author Kristian Rosenvold
35 * @noinspection UnusedDeclaration
36 */
37 public class ProviderDetector
38 {
39
40 public static Set<String> getServiceNames( Class<?> clazz, ClassLoader classLoader )
41 throws IOException
42 {
43 final String resourceName = "META-INF/services/" + clazz.getName();
44
45 if ( classLoader == null )
46 {
47 return Collections.emptySet();
48 }
49 final Enumeration<URL> urlEnumeration = classLoader.getResources( resourceName );
50 return getNames( urlEnumeration );
51 }
52
53
54 /**
55 * Method loadServices loads the services of a class that are
56 * defined using the SPI mechanism.
57 *
58 * @param urlEnumeration The urls from the resource
59 * @return The set of service provider names
60 * @throws IOException When reading the streams fails
61 */
62 private static Set<String> getNames( final Enumeration<URL> urlEnumeration )
63 throws IOException
64 {
65 final Set<String> names = new HashSet<String>();
66 nextUrl:
67 while ( urlEnumeration.hasMoreElements() )
68 {
69 final URL url = urlEnumeration.nextElement();
70 final BufferedReader reader = getReader( url );
71 try
72 {
73 String line;
74 while ( ( line = reader.readLine() ) != null )
75 {
76 int ci = line.indexOf( '#' );
77 if ( ci >= 0 )
78 {
79 line = line.substring( 0, ci );
80 }
81 line = line.trim();
82 int n = line.length();
83 if ( n == 0 )
84 {
85 continue; // next line
86 }
87
88 if ( ( line.indexOf( ' ' ) >= 0 ) || ( line.indexOf( '\t' ) >= 0 ) )
89 {
90 continue nextUrl; // next url
91 }
92 char cp = line.charAt( 0 ); // should use codePointAt but this is JDK1.3
93 if ( !Character.isJavaIdentifierStart( cp ) )
94 {
95 continue nextUrl; // next url
96 }
97 for ( int i = 1; i < n; i++ )
98 {
99 cp = line.charAt( i ); // should use codePointAt but this is JDK1.3
100 if ( !Character.isJavaIdentifierPart( cp ) && ( cp != '.' ) )
101 {
102 continue nextUrl; // next url
103 }
104 }
105 if ( !names.contains( line ) )
106 {
107 names.add( line );
108 }
109 }
110 }
111 finally
112 {
113 reader.close();
114 }
115 }
116
117 return names;
118 }
119
120 private static BufferedReader getReader( URL url )
121 throws IOException
122 {
123 final InputStream inputStream = url.openStream();
124 final InputStreamReader inputStreamReader = new InputStreamReader( inputStream );
125 return new BufferedReader( inputStreamReader );
126 }
127 }