mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#1657 Add Mappers.getMapperClass for getting the class of a Mapper
This commit is contained in:
parent
743361ca45
commit
0e33ad4bbc
@ -53,14 +53,7 @@ public class Mappers {
|
|||||||
*/
|
*/
|
||||||
public static <T> T getMapper(Class<T> clazz) {
|
public static <T> T getMapper(Class<T> clazz) {
|
||||||
try {
|
try {
|
||||||
List<ClassLoader> classLoaders = new ArrayList<>( 3 );
|
List<ClassLoader> classLoaders = collectClassLoaders( clazz.getClassLoader() );
|
||||||
classLoaders.add( clazz.getClassLoader() );
|
|
||||||
|
|
||||||
if ( Thread.currentThread().getContextClassLoader() != null ) {
|
|
||||||
classLoaders.add( Thread.currentThread().getContextClassLoader() );
|
|
||||||
}
|
|
||||||
|
|
||||||
classLoaders.add( Mappers.class.getClassLoader() );
|
|
||||||
|
|
||||||
return getMapper( clazz, classLoaders );
|
return getMapper( clazz, classLoaders );
|
||||||
}
|
}
|
||||||
@ -88,23 +81,88 @@ public class Mappers {
|
|||||||
Class<T> implementation = (Class<T>) classLoader.loadClass( clazz.getName() + IMPLEMENTATION_SUFFIX );
|
Class<T> implementation = (Class<T>) classLoader.loadClass( clazz.getName() + IMPLEMENTATION_SUFFIX );
|
||||||
Constructor<T> constructor = implementation.getDeclaredConstructor();
|
Constructor<T> constructor = implementation.getDeclaredConstructor();
|
||||||
constructor.setAccessible( true );
|
constructor.setAccessible( true );
|
||||||
|
|
||||||
return constructor.newInstance();
|
return constructor.newInstance();
|
||||||
}
|
}
|
||||||
catch (ClassNotFoundException e) {
|
catch (ClassNotFoundException e) {
|
||||||
ServiceLoader<T> loader = ServiceLoader.load( clazz, classLoader );
|
return getMapperFromServiceLoader( clazz, classLoader );
|
||||||
|
|
||||||
if ( loader != null ) {
|
|
||||||
for ( T mapper : loader ) {
|
|
||||||
if ( mapper != null ) {
|
|
||||||
return mapper;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
catch ( InstantiationException | InvocationTargetException | IllegalAccessException e) {
|
catch ( InstantiationException | InvocationTargetException | IllegalAccessException e) {
|
||||||
throw new RuntimeException( e );
|
throw new RuntimeException( e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the class of the implementation for the given mapper type.
|
||||||
|
*
|
||||||
|
* @param clazz The type of the mapper to return.
|
||||||
|
* @param <T> The type of the mapper to create.
|
||||||
|
*
|
||||||
|
* @return A class of the implementation for the given mapper type.
|
||||||
|
*
|
||||||
|
* @since 1.3
|
||||||
|
*/
|
||||||
|
public static <T> Class<? extends T> getMapperClass(Class<T> clazz) {
|
||||||
|
try {
|
||||||
|
List<ClassLoader> classLoaders = collectClassLoaders( clazz.getClassLoader() );
|
||||||
|
|
||||||
|
return getMapperClass( clazz, classLoaders );
|
||||||
|
}
|
||||||
|
catch ( ClassNotFoundException e ) {
|
||||||
|
throw new RuntimeException( e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> Class<? extends T> getMapperClass(Class<T> mapperType, Iterable<ClassLoader> classLoaders)
|
||||||
|
throws ClassNotFoundException {
|
||||||
|
|
||||||
|
for ( ClassLoader classLoader : classLoaders ) {
|
||||||
|
Class<? extends T> mapperClass = doGetMapperClass( mapperType, classLoader );
|
||||||
|
if ( mapperClass != null ) {
|
||||||
|
return mapperClass;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ClassNotFoundException( "Cannot find implementation for " + mapperType.getName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static <T> Class<? extends T> doGetMapperClass(Class<T> clazz, ClassLoader classLoader) {
|
||||||
|
try {
|
||||||
|
return (Class<? extends T>) classLoader.loadClass( clazz.getName() + IMPLEMENTATION_SUFFIX );
|
||||||
|
}
|
||||||
|
catch ( ClassNotFoundException e ) {
|
||||||
|
T mapper = getMapperFromServiceLoader( clazz, classLoader );
|
||||||
|
if ( mapper != null ) {
|
||||||
|
return (Class<? extends T>) mapper.getClass();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> T getMapperFromServiceLoader(Class<T> clazz, ClassLoader classLoader) {
|
||||||
|
ServiceLoader<T> loader = ServiceLoader.load( clazz, classLoader );
|
||||||
|
|
||||||
|
for ( T mapper : loader ) {
|
||||||
|
if ( mapper != null ) {
|
||||||
|
return mapper;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<ClassLoader> collectClassLoaders(ClassLoader classLoader) {
|
||||||
|
List<ClassLoader> classLoaders = new ArrayList<>( 3 );
|
||||||
|
classLoaders.add( classLoader );
|
||||||
|
|
||||||
|
if ( Thread.currentThread().getContextClassLoader() != null ) {
|
||||||
|
classLoaders.add( Thread.currentThread().getContextClassLoader() );
|
||||||
|
}
|
||||||
|
|
||||||
|
classLoaders.add( Mappers.class.getClassLoader() );
|
||||||
|
|
||||||
|
return classLoaders;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,18 +25,37 @@ public class MappersTest {
|
|||||||
assertThat( mapper ).isNotNull();
|
assertThat( mapper ).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldReturnImplementationClass() {
|
||||||
|
|
||||||
|
Class<? extends Foo> mapperClass = Mappers.getMapperClass( Foo.class );
|
||||||
|
assertThat( mapperClass ).isNotNull();
|
||||||
|
assertThat( mapperClass ).isNotExactlyInstanceOf( Foo.class );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if an implementation of a nested mapper can be found. This is a special case since
|
* Checks if an implementation of a nested mapper can be found. This is a special case since
|
||||||
* it is named
|
* it is named
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void findsNestedMapperImpl() throws Exception {
|
public void findsNestedMapperImpl() {
|
||||||
assertThat( Mappers.getMapper( SomeClass.Foo.class ) ).isNotNull();
|
assertThat( Mappers.getMapper( SomeClass.Foo.class ) ).isNotNull();
|
||||||
assertThat( Mappers.getMapper( SomeClass.NestedClass.Foo.class ) ).isNotNull();
|
assertThat( Mappers.getMapper( SomeClass.NestedClass.Foo.class ) ).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findsNestedMapperImplClass() {
|
||||||
|
assertThat( Mappers.getMapperClass( SomeClass.Foo.class ) ).isNotNull();
|
||||||
|
assertThat( Mappers.getMapperClass( SomeClass.NestedClass.Foo.class ) ).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldReturnPackagePrivateImplementationInstance() {
|
public void shouldReturnPackagePrivateImplementationInstance() {
|
||||||
assertThat( Mappers.getMapper( PackagePrivateMapper.class ) ).isNotNull();
|
assertThat( Mappers.getMapper( PackagePrivateMapper.class ) ).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldReturnPackagePrivateImplementationClass() {
|
||||||
|
assertThat( Mappers.getMapperClass( PackagePrivateMapper.class ) ).isNotNull();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user