From c9bc1df132e3498eca7bcd92fd91e260bcc195db Mon Sep 17 00:00:00 2001 From: Gervais Blaise Date: Thu, 12 Jul 2018 22:12:09 +0200 Subject: [PATCH] Allow package-private mapper Use and make the default constructor accessible to create the mapper instance. fixes #1365 --- .../java/org/mapstruct/factory/Mappers.java | 22 +++++++++++++----- .../org/mapstruct/factory/MappersTest.java | 5 ++++ .../factory/PackagePrivateMapper.java | 23 +++++++++++++++++++ .../factory/PackagePrivateMapperImpl.java | 22 ++++++++++++++++++ 4 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 core-common/src/test/java/org/mapstruct/factory/PackagePrivateMapper.java create mode 100644 core-common/src/test/java/org/mapstruct/factory/PackagePrivateMapperImpl.java diff --git a/core-common/src/main/java/org/mapstruct/factory/Mappers.java b/core-common/src/main/java/org/mapstruct/factory/Mappers.java index e74004023..44ab7ae4f 100644 --- a/core-common/src/main/java/org/mapstruct/factory/Mappers.java +++ b/core-common/src/main/java/org/mapstruct/factory/Mappers.java @@ -18,6 +18,8 @@ */ package org.mapstruct.factory; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; import java.util.ServiceLoader; @@ -78,10 +80,13 @@ public class Mappers { catch ( ClassNotFoundException e ) { throw new RuntimeException( e ); } + catch ( NoSuchMethodException e) { + throw new RuntimeException( e ); + } } - private static T getMapper( - Class mapperType, Iterable classLoaders) throws ClassNotFoundException { + private static T getMapper(Class mapperType, Iterable classLoaders) + throws ClassNotFoundException, NoSuchMethodException { for ( ClassLoader classLoader : classLoaders ) { T mapper = doGetMapper( mapperType, classLoader ); @@ -93,11 +98,13 @@ public class Mappers { throw new ClassNotFoundException("Cannot find implementation for " + mapperType.getName() ); } - private static T doGetMapper(Class clazz, ClassLoader classLoader) { + private static T doGetMapper(Class clazz, ClassLoader classLoader) throws NoSuchMethodException { try { - @SuppressWarnings("unchecked") - T mapper = (T) classLoader.loadClass( clazz.getName() + IMPLEMENTATION_SUFFIX ).newInstance(); - return mapper; + @SuppressWarnings( "unchecked" ) + Class implementation = (Class) classLoader.loadClass( clazz.getName() + IMPLEMENTATION_SUFFIX ); + Constructor constructor = implementation.getDeclaredConstructor(); + constructor.setAccessible( true ); + return constructor.newInstance(); } catch (ClassNotFoundException e) { ServiceLoader loader = ServiceLoader.load( clazz, classLoader ); @@ -118,5 +125,8 @@ public class Mappers { catch (IllegalAccessException e) { throw new RuntimeException( e ); } + catch (InvocationTargetException e) { + throw new RuntimeException( e ); + } } } diff --git a/core-common/src/test/java/org/mapstruct/factory/MappersTest.java b/core-common/src/test/java/org/mapstruct/factory/MappersTest.java index 990907fe0..1a0da2626 100644 --- a/core-common/src/test/java/org/mapstruct/factory/MappersTest.java +++ b/core-common/src/test/java/org/mapstruct/factory/MappersTest.java @@ -47,4 +47,9 @@ public class MappersTest { assertThat( Mappers.getMapper( SomeClass.Foo.class ) ).isNotNull(); assertThat( Mappers.getMapper( SomeClass.NestedClass.Foo.class ) ).isNotNull(); } + + @Test + public void shouldReturnPackagePrivateImplementationInstance() { + assertThat( Mappers.getMapper( PackagePrivateMapper.class ) ).isNotNull(); + } } diff --git a/core-common/src/test/java/org/mapstruct/factory/PackagePrivateMapper.java b/core-common/src/test/java/org/mapstruct/factory/PackagePrivateMapper.java new file mode 100644 index 000000000..7d5e4738a --- /dev/null +++ b/core-common/src/test/java/org/mapstruct/factory/PackagePrivateMapper.java @@ -0,0 +1,23 @@ +/** + * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * 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.mapstruct.factory; + +interface PackagePrivateMapper { + +} diff --git a/core-common/src/test/java/org/mapstruct/factory/PackagePrivateMapperImpl.java b/core-common/src/test/java/org/mapstruct/factory/PackagePrivateMapperImpl.java new file mode 100644 index 000000000..dd8ee8931 --- /dev/null +++ b/core-common/src/test/java/org/mapstruct/factory/PackagePrivateMapperImpl.java @@ -0,0 +1,22 @@ +/** + * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * 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.mapstruct.factory; + +class PackagePrivateMapperImpl implements PackagePrivateMapper { +}