fr.opensagres.xdocreport.core.internal.JDKServiceLoader Maven / Gradle / Ivy
/**
* Copyright (C) 2011-2015 The XDocReport Team
*
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package fr.opensagres.xdocreport.core.internal;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import fr.opensagres.xdocreport.core.logging.LogUtils;
/**
* JDK ServiceLoader is used to load services declared in the META-INF/services/MyClass. Switch JDK using, it uses:
*
* - java.util.ServiceLoader if XDocReport works on Java6. For example :
*
* Iterator discoveries =
ServiceLoader.load( registryType, getClass().getClassLoader() ).iterator();
*
*
* - javax.imageio.spi.ServiceRegistry if XDocReport works on Java5. For example :
*
* Iterator discoveries =
ServiceRegistry.lookupProviders( registryType, getClass().getClassLoader() );
*
*
*
*/
public abstract class JDKServiceLoader
{
private static final Logger LOGGER = LogUtils.getLogger( JDKServiceLoader.class.getName() );
// The JDK Service loader to use.
private static JDKServiceLoader JDK_SERVICE_LOADER;
static
{
ClassLoader classLoader = JDKServiceLoader.class.getClassLoader();
try
{
// At first, try to use JDK6 java.util.ServiceLoader
JDK_SERVICE_LOADER = new JDK6ServiceLoader( classLoader );
if ( LOGGER.isLoggable( Level.FINE ) )
{
LOGGER.fine( "Uses JDK6 java.util.ServiceLoader to load services." );
}
}
catch ( Throwable e )
{
// JDK6 is not used here, uses the JDK5 javax.imageio.spi.ServiceRegistry
try
{
JDK_SERVICE_LOADER = new JDK5ServiceLoader( classLoader );
if ( LOGGER.isLoggable( Level.FINE ) )
{
LOGGER.fine( "Uses JDK5 javax.imageio.spi.ServiceRegistry to load services." );
}
}
catch ( Throwable e1 )
{
// Should never thrown.
if ( LOGGER.isLoggable( Level.SEVERE ) )
{
LOGGER.log( Level.SEVERE, "Error while initialization of JDKServiceLoader", e1 );
}
}
}
}
public static Iterator lookupProviders( Class providerClass, ClassLoader loader )
{
try
{
return JDK_SERVICE_LOADER.lookupProvidersFromJDK( providerClass, loader );
}
catch ( Exception e )
{
throw new RuntimeException( e );
}
}
protected abstract Iterator lookupProvidersFromJDK( Class providerClass, ClassLoader loader )
throws Exception;
private static class JDK5ServiceLoader
extends JDKServiceLoader
{
private final Method lookupProvidersMethod;
public JDK5ServiceLoader( ClassLoader classLoader )
throws ClassNotFoundException, SecurityException, NoSuchMethodException
{
Class slc = classLoader.loadClass( "javax.imageio.spi.ServiceRegistry" );
lookupProvidersMethod = slc.getMethod( "lookupProviders", Class.class, ClassLoader.class );
}
@SuppressWarnings( "unchecked" )
@Override
protected Iterator lookupProvidersFromJDK( Class providerClass, ClassLoader loader )
throws Exception
{
return (Iterator) lookupProvidersMethod.invoke( null, providerClass, loader );
}
}
private static class JDK6ServiceLoader
extends JDKServiceLoader
{
private Method loadMethod;
private Method iteratorMethod;
public JDK6ServiceLoader( ClassLoader classLoader )
throws ClassNotFoundException, SecurityException, NoSuchMethodException
{
Class slc = classLoader.loadClass( "java.util.ServiceLoader" );
loadMethod = slc.getMethod( "load", Class.class, ClassLoader.class );
iteratorMethod = slc.getMethod( "iterator" );
}
@SuppressWarnings( "unchecked" )
@Override
protected Iterator lookupProvidersFromJDK( Class providerClass, ClassLoader loader )
throws Exception
{
Object serviceLoader = loadMethod.invoke( null, providerClass, loader );
return (Iterator) iteratorMethod.invoke( serviceLoader );
}
}
}