#801 Trying to load mapper implementation types via the mapper interface's loader first

This commit is contained in:
Gunnar Morling 2016-07-05 21:46:45 +02:00
parent 051177e409
commit c47fd95d04

View File

@ -18,10 +18,12 @@
*/
package org.mapstruct.factory;
import org.mapstruct.Mapper;
import java.util.ArrayList;
import java.util.List;
import java.util.ServiceLoader;
import org.mapstruct.Mapper;
/**
* Factory for obtaining mapper instances if no explicit component model such as CDI is configured via
* {@link Mapper#componentModel()}.
@ -62,19 +64,36 @@ public class Mappers {
*/
public static <T> T getMapper(Class<T> clazz) {
try {
List<ClassLoader> classLoaders = new ArrayList<ClassLoader>( 3 );
classLoaders.add( clazz.getClassLoader() );
// Check that
// - clazz is an interface
// - the implementation type implements clazz
// - clazz is annotated with @Mapper
//
// Use privileged action
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if ( classLoader == null ) {
classLoader = Mappers.class.getClassLoader();
if ( Thread.currentThread().getContextClassLoader() != null ) {
classLoaders.add( Thread.currentThread().getContextClassLoader() );
}
classLoaders.add( Mappers.class.getClassLoader() );
return getMapper( clazz, classLoaders );
}
catch ( ClassNotFoundException e ) {
throw new RuntimeException( e );
}
}
private static <T> T getMapper(
Class<T> mapperType, Iterable<ClassLoader> classLoaders) throws ClassNotFoundException {
for ( ClassLoader classLoader : classLoaders ) {
T mapper = doGetMapper( mapperType, classLoader );
if ( mapper != null ) {
return mapper;
}
}
throw new ClassNotFoundException("Cannot find implementation for " + mapperType.getName() );
}
private static <T> T doGetMapper(Class<T> clazz, ClassLoader classLoader) {
try {
@SuppressWarnings("unchecked")
T mapper = (T) classLoader.loadClass( clazz.getName() + IMPLEMENTATION_SUFFIX ).newInstance();
@ -91,10 +110,12 @@ public class Mappers {
}
}
throw new ClassNotFoundException("Cannot find implementation for " + clazz.getName());
return null;
}
catch (InstantiationException e) {
throw new RuntimeException( e );
}
catch ( Exception e ) {
catch (IllegalAccessException e) {
throw new RuntimeException( e );
}
}