KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > beehive > netui > util > internal > DiscoveryUtils


1 /*
2  * Copyright 2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * $Header:$
17  */

18 package org.apache.beehive.netui.util.internal;
19
20 import org.apache.beehive.netui.util.logging.Logger;
21
22 import java.io.IOException JavaDoc;
23 import java.io.BufferedReader JavaDoc;
24 import java.io.InputStreamReader JavaDoc;
25 import java.io.InputStream JavaDoc;
26 import java.util.Enumeration JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.Map JavaDoc;
29 import java.net.URL JavaDoc;
30
31
32 /**
33  * Utility methods for discovering implementor classes on the classpath. An implementor class is declared in the
34  * standard way, in a file within META-INF/services where the file name is the class name of the desired interface, and
35  * the file contains the class name of the implementation. For example, to declare test.MyServiceImpl as a
36  * test.MyService implementation, the file META-INF/services/test.MyService is put on classpath (e.g., in a JAR),
37  * with contents "test.MyServiceImpl".
38  */

39 public class DiscoveryUtils
40 {
41     private static final Logger _log = Logger.getInstance( DiscoveryUtils.class );
42     
43     
44     /**
45      * Get the ClassLoader from which implementor classes will be discovered and loaded.
46      */

47     public static ClassLoader JavaDoc getClassLoader()
48     {
49         try
50         {
51             ClassLoader JavaDoc cl = Thread.currentThread().getContextClassLoader();
52             if ( cl != null ) return cl;
53         }
54         catch ( SecurityException JavaDoc e )
55         {
56             if ( _log.isDebugEnabled() )
57             {
58                 _log.debug( "Could not get thread context classloader.", e );
59             }
60         }
61         
62         if ( _log.isTraceEnabled() )
63         {
64             _log.trace( "Can't use thread context classloader; using classloader for " + DiscoveryUtils.class.getName() );
65         }
66         
67         return DiscoveryUtils.class.getClassLoader();
68     }
69     
70     /**
71      * Get all implementor classes (on the context classpath) that implement a given interface.
72      *
73      * @param interfaceType the Class that represents the interface.
74      * @return an array of Classes that are implementations of <code>interfaceType</code>.
75      */

76     public static Class JavaDoc[] getImplementorClasses( Class JavaDoc interfaceType )
77     {
78         String JavaDoc interfaceName = interfaceType.getName();
79         ArrayList JavaDoc/*< Class >*/ classes = new ArrayList JavaDoc/*< Class >*/();
80         ClassLoader JavaDoc classLoader = getClassLoader();
81         
82         try
83         {
84             Enumeration JavaDoc e = classLoader.getResources( "META-INF/services/" + interfaceName );
85             
86             while ( e.hasMoreElements() )
87             {
88                 URL JavaDoc url = ( URL JavaDoc ) e.nextElement();
89                 
90                 if ( _log.isTraceEnabled() )
91                 {
92                     _log.trace( "Found implementor entry for interface " + interfaceName + " at " + url );
93                 }
94                 
95                 InputStream JavaDoc is = null;
96                 String JavaDoc className = null;
97                 
98                 try
99                 {
100                     is = url.openStream();
101                     BufferedReader JavaDoc reader = new BufferedReader JavaDoc( new InputStreamReader JavaDoc( is ) );
102                     className = reader.readLine().trim();
103                     Class JavaDoc implementorClass = loadImplementorClass( className, interfaceType, classLoader );
104                     if ( implementorClass != null ) classes.add( implementorClass );
105                 }
106                 catch ( IOException JavaDoc ioe )
107                 {
108                     _log.error( "Could not read implementor class entry at + " + url );
109                 }
110                 finally
111                 {
112                     if ( is != null ) is.close();
113                 }
114             }
115         }
116         catch ( IOException JavaDoc e )
117         {
118             _log.error( "Could not discover implementors for " + interfaceName, e );
119         }
120         
121         return ( Class JavaDoc[] ) classes.toArray( new Class JavaDoc[0] );
122     }
123     
124     public static Object JavaDoc newImplementorInstance( String JavaDoc className, Class JavaDoc interfaceType )
125     {
126         Class JavaDoc implementorClass = loadImplementorClass( className, interfaceType );
127         
128         if ( implementorClass != null )
129         {
130             try
131             {
132                 return implementorClass.newInstance();
133             }
134             catch ( IllegalAccessException JavaDoc e )
135             {
136                 _log.error( "Could not instantiate " + className + " for interface " + interfaceType.getName(), e );
137             }
138             catch ( InstantiationException JavaDoc e )
139             {
140                 _log.error( "Could not instantiate " + className + " for interface " + interfaceType.getName(), e );
141             }
142         }
143         
144         return null;
145     }
146     
147     /**
148      * Load an implementor class from the context classloader.
149      *
150      * @param className the name of the implementor class.
151      * @param interfaceType the interface that the given class should implement.
152      * @return the implementor Class, or <code>null</code> if an error occurred (the error will be logged).
153      */

154     public static Class JavaDoc loadImplementorClass( String JavaDoc className, Class JavaDoc interfaceType )
155     {
156         return loadImplementorClass( className, interfaceType, getClassLoader() );
157     }
158     
159     /**
160      * Load an implementor class from the context classloader.
161      *
162      * @param className the name of the implementor class.
163      * @param interfaceType the interface that the given class should implement.
164      * @param classLoader the ClassLoader from which to load the implementor class.
165      * @return the implementor Class, or <code>null</code> if an error occurred (the error will be logged).
166      */

167     private static Class JavaDoc loadImplementorClass( String JavaDoc className, Class JavaDoc interfaceType, ClassLoader JavaDoc classLoader )
168     {
169         try
170         {
171             if ( _log.isDebugEnabled() )
172             {
173                 _log.debug( "Trying to load implementor class for interface " + interfaceType.getName()
174                             + ": " + className );
175             }
176             
177             Class JavaDoc implementorClass = classLoader.loadClass( className );
178             
179             if ( interfaceType.isAssignableFrom( implementorClass ) )
180             {
181                 return implementorClass;
182             }
183             else
184             {
185                 _log.error( "Implementor class " + className + " does not implement interface "
186                             + interfaceType.getName() );
187             }
188         }
189         catch ( ClassNotFoundException JavaDoc cnfe )
190         {
191             //
192
// This will happen when the user class was built against an out-of-date interface.
193
//
194
_log.error( "Could not find implementor class " + className + " for interface " + interfaceType.getName(),
195                         cnfe );
196         }
197         catch ( LinkageError JavaDoc le )
198         {
199             _log.error( "Linkage error when loading implementor class " + className + " for interface "
200                         + interfaceType.getName(), le );
201         }
202         
203         return null;
204     }
205 }
206
Popular Tags