org.sql.generation.api.vendor.internal.ServiceLoader Maven / Gradle / Ivy
/*
* Copyright 2008 Niclas Hedhman. All rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sql.generation.api.vendor.internal;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
/**
*
* This is a copy from file located Qi4j's bootstrap project, since there is no java.util.ServiceLoader in Java 1.5.
* This is from org.qi4j.bootstrap.internal package.
*
*
*
* Update 27.9.2010 - I (Stanislav Muhametsin) made a small syntactical change to private/protected methods in order to
* remove compile warnings.
*
*
* @see http://download.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html
*/
public final class ServiceLoader
{
private final static LinkedList loaders = new LinkedList();
static
{
addClassloader( ServiceLoader.class.getClassLoader() );
}
public static void addClassloader( ClassLoader loader )
{
loaders.add( loader );
}
public static void removeClassloader( ClassLoader loader )
{
loaders.remove( loader );
}
public Iterable providers( Class neededType )
throws IOException
{
LinkedList result = new LinkedList();
for( ClassLoader loader : loaders )
{
Enumeration cfg = loader.getResources( "META-INF/services/" + neededType.getName() );
while( cfg.hasMoreElements() )
{
URL rc = (URL) cfg.nextElement();
processResource( loader, result, rc, neededType );
}
}
return result;
}
public T firstProvider( Class neededType )
throws IOException
{
final Iterator allProviders = providers( neededType ).iterator();
if( allProviders.hasNext() )
{
return allProviders.next();
}
System.err.println( "No provider found for " + neededType + "." );
return null;
}
private void processResource( ClassLoader classLoader, LinkedList result, URL rc, Class neededType )
throws IOException
{
InputStream in = null;
BufferedReader rd = null;
try
{
in = rc.openStream();
rd = new BufferedReader( new InputStreamReader( in, "UTF-8" ) );
String line = rd.readLine();
while( null != line )
{
String providerClassName = trimLine( line );
if( line.length() > 0 )
{
processProvider( result, classLoader, providerClassName, neededType );
}
line = rd.readLine();
}
}
finally
{
if( rd != null )
{
rd.close();
}
if( in != null )
{
in.close();
}
}
}
private String trimLine( String line )
{
int hashPos = line.indexOf( '#' );
if( hashPos >= 0 )
{
line = line.substring( 0, hashPos );
}
line = line.trim();
return line;
}
private void processProvider( LinkedList result, ClassLoader classLoader, String providerClassName,
Class neededType )
{
Class provider = loadProvider( classLoader, providerClassName, neededType );
if( provider == null )
{
return;
}
T instance = instantiateProvider( provider );
if( instance == null )
{
return;
}
if( !result.contains( instance ) )
{
result.add( instance );
}
}
private Class loadProvider( ClassLoader ldr, String providerClassName, Class neededType )
{
try
{
final Class providerClass = ldr.loadClass( providerClassName );
return providerClass.asSubclass( neededType );
}
catch( ClassCastException ex )
{
System.err.println( "Class " + providerClassName + " was not of " + neededType.getName() + " subtype." );
}
catch( ClassNotFoundException ex )
{
System.err.println( "Class " + providerClassName + " was not found. Skipping." );
}
return null;
}
private T instantiateProvider( Class provider )
{
try
{
return provider.newInstance();
}
catch( InstantiationException ex )
{
System.err.println( "Class " + provider.getName() + " is an interface or abstract class." );
}
catch( IllegalAccessException ex )
{
System.err.println( "Class " + provider.getName()
+ " is not accessible. Make sure it is public and have a public no-args constructor." );
}
return null;
}
}