View Javadoc

1   package com.aragost.javahg.internals;
2   
3   import com.google.common.io.Closeables;
4   import java.io.BufferedReader;
5   import java.io.InputStreamReader;
6   import java.net.URL;
7   
8   /**
9    * The ServiceLoader searches for Service implementations in META-INF/services.
10   * This class emulates the behavior of ServiceLoader introduced in Java 1.6.
11   *
12   * @author Sebastian Sdorra
13   */
14  public final class ServiceLoader
15  {
16    
17    private static final String SERVICE_PREFIX = "META-INF/services/";
18    
19    /**
20     * This method is shorthand for {@link #loadService(java.lang.ClassLoader, java.lang.Class)}
21     * with the context classloader.
22     * 
23     * @param serviceClass classloader used to load the resource from META-INF/services
24     * 
25     * @return service implementation or null
26     * 
27     * @throws ServiceException 
28     */
29    public static <S> S loadService( Class<S> serviceClass ) throws ServiceException {
30        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
31        if ( classLoader == null ){
32            classLoader = Utils.class.getClassLoader();
33        }
34        return loadService(classLoader, serviceClass);
35    }
36    
37    /**
38     * Returns a implementation of the given service or null if no service could 
39     * be found.
40     * 
41     * @param classLoader classloader used to load the resource from META-INF/services
42     * @param serviceClass service class to load
43     * 
44     * @return service implementation or null
45     * @throws ServiceException 
46     */
47    public static <S> S loadService(ClassLoader classLoader, Class<S> serviceClass ) throws ServiceException{
48        S service = null;
49        String name = serviceClass.getName();
50        URL resource = classLoader.getResource(SERVICE_PREFIX.concat(name));
51        if ( resource != null ){
52            BufferedReader reader = null;
53            try {
54                reader = new BufferedReader(new InputStreamReader(resource.openStream(), "UTF-8"));
55                String line = reader.readLine();
56                while (line != null){
57                    int comment = line.indexOf("#");
58                    if ( comment >= 0 ){
59                        line = line.substring(0, comment);
60                    }
61                    line = line.trim();
62                    if ( line.length() > 0 ){
63                        service = (S) Class.forName(line).newInstance();
64                        break;
65                    }
66                    line = reader.readLine();
67                }
68            } catch ( Exception ex ){
69                throw new ServiceException(
70                  "could not load service for class ".concat(name), ex);
71            } finally {
72                Closeables.closeQuietly(reader);
73            }
74        }
75        return service;
76    }
77  }