mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#611 Allow nested declaration of Mappers
* #611 Allow nested declaration of Mappers Up until now, if a Mapper was declared as a nested interface, say EnclosingClass.NestedMapper, the implementation of the mapper was generated as NestedMapperImpl in the same package. The Mappers factory class then tried to load EnclosingClass$NestedMapperImpl, which would fail.
This commit is contained in:
parent
3b9584ff13
commit
00385a1cdb
@ -22,6 +22,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mapstruct.test.model.Foo;
|
||||
import org.mapstruct.test.model.SomeClass;
|
||||
|
||||
/**
|
||||
* Unit test for {@link Mappers}.
|
||||
@ -36,4 +37,14 @@ public class MappersTest {
|
||||
Foo mapper = Mappers.getMapper( Foo.class );
|
||||
assertThat( mapper ).isNotNull();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an implementation of a nested mapper can be found. This is a special case since
|
||||
* it is named
|
||||
*/
|
||||
@Test
|
||||
public void findsNestedMapperImpl() throws Exception {
|
||||
assertThat( Mappers.getMapper( SomeClass.Foo.class ) ).isNotNull();
|
||||
assertThat( Mappers.getMapper( SomeClass.NestedClass.Foo.class ) ).isNotNull();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* 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.test.model;
|
||||
|
||||
/**
|
||||
* For testing naming of implementations of nested mappers (issue 611).
|
||||
*
|
||||
* @author Tillmann Gaida
|
||||
*/
|
||||
/*
|
||||
* Turn off checkstyle since the underscore introduced by issue 611 violates the class naming
|
||||
* convention.
|
||||
*/
|
||||
// CHECKSTYLE:OFF
|
||||
public class SomeClass$FooImpl implements SomeClass.Foo {
|
||||
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* 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.test.model;
|
||||
|
||||
/**
|
||||
* For testing naming of implementations of nested mappers (issue 611).
|
||||
*
|
||||
* @author Tillmann Gaida
|
||||
*/
|
||||
/*
|
||||
* Turn off checkstyle since the underscore introduced by issue 611 violates the class naming
|
||||
* convention.
|
||||
*/
|
||||
// CHECKSTYLE:OFF
|
||||
public class SomeClass$NestedClass$FooImpl implements SomeClass.NestedClass.Foo {
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* 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.test.model;
|
||||
|
||||
/**
|
||||
* The sole purpose of this class is to have a place to nest the Foo interface.
|
||||
*
|
||||
* @author Tillmann Gaida
|
||||
*/
|
||||
public class SomeClass {
|
||||
public interface Foo { }
|
||||
|
||||
public static class NestedClass {
|
||||
public interface Foo { }
|
||||
}
|
||||
}
|
@ -111,7 +111,7 @@ public class Decorator extends GeneratedType {
|
||||
|
||||
public Decorator build() {
|
||||
String implementationName = implName.replace( Mapper.CLASS_NAME_PLACEHOLDER,
|
||||
mapperElement.getSimpleName() );
|
||||
Mapper.getFlatName( mapperElement ) );
|
||||
|
||||
Type decoratorType = typeFactory.getType( decoratorPrism.value() );
|
||||
DecoratorConstructor decoratorConstructor = new DecoratorConstructor(
|
||||
|
@ -21,6 +21,7 @@ package org.mapstruct.ap.internal.model;
|
||||
import java.util.List;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.util.Elements;
|
||||
@ -153,7 +154,7 @@ public class Mapper extends GeneratedType {
|
||||
}
|
||||
|
||||
public Mapper build() {
|
||||
String implementationName = implName.replace( CLASS_NAME_PLACEHOLDER, element.getSimpleName() ) +
|
||||
String implementationName = implName.replace( CLASS_NAME_PLACEHOLDER, getFlatName( element ) ) +
|
||||
( decorator == null ? "" : "_" );
|
||||
|
||||
String elementPackage = elementUtils.getPackageOf( element ).getQualifiedName().toString();
|
||||
@ -199,4 +200,20 @@ public class Mapper extends GeneratedType {
|
||||
protected String getTemplateName() {
|
||||
return getTemplateNameForClass( GeneratedType.class );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the same as {@link Class#getName()} but without the package declaration.
|
||||
*/
|
||||
public static String getFlatName(TypeElement element) {
|
||||
if (!(element.getEnclosingElement() instanceof TypeElement)) {
|
||||
return element.getSimpleName().toString();
|
||||
}
|
||||
StringBuilder nameBuilder = new StringBuilder( element.getSimpleName().toString() );
|
||||
for (Element enclosing = element.getEnclosingElement(); enclosing instanceof TypeElement; enclosing =
|
||||
enclosing.getEnclosingElement()) {
|
||||
nameBuilder.insert( 0, '$' );
|
||||
nameBuilder.insert( 0, enclosing.getSimpleName().toString() );
|
||||
}
|
||||
return nameBuilder.toString();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,71 @@
|
||||
/**
|
||||
* 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.ap.test.bugs._611;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mapstruct.ap.testutil.IssueKey;
|
||||
import org.mapstruct.ap.testutil.WithClasses;
|
||||
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Tillmann Gaida
|
||||
*/
|
||||
@IssueKey("611")
|
||||
@RunWith(AnnotationProcessorTestRunner.class)
|
||||
@WithClasses({
|
||||
SomeClass.class,
|
||||
SomeOtherClass.class
|
||||
})
|
||||
public class Issue611Test {
|
||||
/**
|
||||
* Checks if an implementation of a nested mapper can be loaded at all.
|
||||
*/
|
||||
@Test
|
||||
public void mapperIsFound() {
|
||||
assertThat( SomeClass.InnerMapper.INSTANCE ).isNotNull();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an implementation of a nested mapper can be loaded which is nested into an already
|
||||
* nested class.
|
||||
*/
|
||||
@Test
|
||||
public void mapperNestedInsideNestedClassIsFound() {
|
||||
assertThat( SomeClass.SomeInnerClass.InnerMapper.INSTANCE ).isNotNull();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if it is possible to load two mapper implementations which have equal simple names
|
||||
* in the same package.
|
||||
*/
|
||||
@Test
|
||||
public void rightMapperIsFound() {
|
||||
SomeClass.InnerMapper.Source source1 = new SomeClass.InnerMapper.Source();
|
||||
SomeOtherClass.InnerMapper.Source source2 = new SomeOtherClass.InnerMapper.Source();
|
||||
|
||||
SomeClass.InnerMapper.Target target1 = SomeClass.InnerMapper.INSTANCE.toTarget( source1 );
|
||||
SomeOtherClass.InnerMapper.Target target2 = SomeOtherClass.InnerMapper.INSTANCE.toTarget( source2 );
|
||||
|
||||
assertThat( target1 ).isExactlyInstanceOf( SomeClass.InnerMapper.Target.class );
|
||||
assertThat( target2 ).isExactlyInstanceOf( SomeOtherClass.InnerMapper.Target.class );
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/**
|
||||
* 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.ap.test.bugs._611;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
* @author Tillmann Gaida
|
||||
*/
|
||||
public class SomeClass {
|
||||
@Mapper
|
||||
public interface InnerMapper {
|
||||
InnerMapper INSTANCE = Mappers.getMapper( InnerMapper.class );
|
||||
|
||||
Target toTarget(Source in);
|
||||
|
||||
class Source {
|
||||
}
|
||||
|
||||
class Target {
|
||||
}
|
||||
}
|
||||
|
||||
public static class SomeInnerClass {
|
||||
@Mapper
|
||||
public interface InnerMapper {
|
||||
InnerMapper INSTANCE = Mappers.getMapper( InnerMapper.class );
|
||||
|
||||
Target toTarget(Source in);
|
||||
|
||||
class Source {
|
||||
}
|
||||
|
||||
class Target {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* 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.ap.test.bugs._611;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
* @author Tillmann Gaida
|
||||
*/
|
||||
public class SomeOtherClass {
|
||||
@Mapper
|
||||
public interface InnerMapper {
|
||||
InnerMapper INSTANCE = Mappers.getMapper( InnerMapper.class );
|
||||
|
||||
Target toTarget(Source in);
|
||||
|
||||
class Source {
|
||||
}
|
||||
|
||||
class Target {
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user