Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: javax/ide/spi/LookupProvider.java


1   package javax.ide.spi;
2   
3   import java.io.BufferedReader;
4   import java.io.IOException;
5   import java.io.InputStream;
6   import java.io.InputStreamReader;
7   
8   import java.net.URL;
9   
10  import java.util.ArrayList;
11  import java.util.Collection;
12  import java.util.Enumeration;
13  import java.util.Iterator;
14  
15  
16  /**
17   * Provides facilities for looking up implementation classes.
18   */
19  public final class LookupProvider 
20  {
21    private LookupProvider() {}
22  
23    /**
24     * Look up and create the an implementation of a specified 
25     * class.<p>
26     * 
27     * The implementation class is stored on a jar in the classpath in the 
28     * META-INF/services/some.class.Name file. This file contains the fully
29     * qualified name of the implementation class of some.class.Name.<p>
30     * 
31     * If there are multiple META-INF/services/some.class.Name files on the 
32     * classpath, the <b>last</b> one wins. This is intentionally different
33     * from the normal classpath precendence order so that it is possible to
34     * override a more general implementation (e.g. a JSR-198 default
35     * implementation of some service) with a specific one (e.g. an IDE 
36     * specific service).
37     * 
38     * @param loader the class loader to look up implementations on.
39     * @param clazz the class to look up an implementation of.
40     * @return the first available implementation of the specified class on the 
41     *    classpath.
42     * 
43     * @throws ProviderNotFoundException if no implementation for the specified
44     *    class could be loaded.
45     */
46    public static Object lookup( ClassLoader loader, Class clazz )
47      throws ProviderNotFoundException
48    {
49      Collection impls = lookupAll( loader, clazz );
50      if ( impls.isEmpty() )
51      {
52        throw new ProviderNotFoundException( "No provider for " + clazz );
53      }
54      for ( Iterator i = impls.iterator(); i.hasNext(); )
55      {
56        Object o = i.next();
57        if ( !i.hasNext() )
58        {
59          return o;
60        }
61      }
62      throw new IllegalStateException();
63    }
64  
65    /**
66     * Look up and create all available implementations of a specified class.<p>
67     * 
68     * The implementation class is stored on a jar in the classpath in the 
69     * META-INF/services/some.class.Name file. This file contains the fully
70     * qualified name of the implementation class of some.class.Name.
71     * 
72     * @param loader the class loader to look up implementations on.
73     * @param clazz the class to look up an implementation of.
74     * @return all available implementations of the specified class on the 
75     *    classpath.
76     * 
77     * @throws ProviderNotFoundException if no implementation for the specified
78     *    class could be loaded.
79     */
80    public static Collection lookupAll( ClassLoader loader, Class clazz ) 
81      throws ProviderNotFoundException
82    {
83      Enumeration en;
84      try
85      {
86        en = loader.getResources( "META-INF/services/" + clazz.getName() );
87      }
88      catch ( IOException ioe )
89      {
90        throw new ProviderNotFoundException( clazz.getName(), ioe );
91      }
92      
93      Collection results = new ArrayList();
94      
95      while ( en.hasMoreElements() )
96      {
97        URL url = (URL) en.nextElement();
98        try
99        {
100         InputStream is = url.openStream();
101         try
102         {
103           BufferedReader reader = new BufferedReader( 
104             new InputStreamReader( is, "UTF-8" ) );
105           while ( true )
106           {
107             String line = reader.readLine();
108             if ( line == null )
109             {
110               break;
111             }
112             line = line.trim();
113             if ( line.length() == 0 ) continue;
114             if ( line.charAt( 0 ) == '#' ) continue;
115             
116             try
117             {
118               Class inst = Class.forName( line, false, loader );
119               
120               if ( !clazz.isAssignableFrom( inst ) )
121               {
122                 throw new ProviderNotFoundException( 
123                   inst + " is not correct type for service " + clazz );
124               }
125               results.add( inst.newInstance() );
126             }
127             catch ( Exception e )
128             {
129               throw new ProviderNotFoundException( "Failed to create service class "+line, 
130                 e );
131             }
132 
133           }
134         }
135         finally
136         {
137           is.close();
138         }
139       }
140       catch ( IOException ioe )
141       {
142         throw new ProviderNotFoundException( "Failed to load service class "+clazz, ioe );
143       }
144 
145     }
146     return results;    
147   }
148 
149 
150 }