mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#253, #254 do not collect methods that override Object#equals(Object) or that are overridden by an already collected method from a sub type
This commit is contained in:
parent
644b5ef65a
commit
c434e1dcd3
@ -22,6 +22,7 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.processing.Messager;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
@ -30,6 +31,7 @@ import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.type.DeclaredType;
|
||||
import javax.lang.model.type.TypeKind;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.lang.model.util.Elements;
|
||||
import javax.lang.model.util.Types;
|
||||
import javax.tools.Diagnostic.Kind;
|
||||
|
||||
@ -62,12 +64,16 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
||||
private Messager messager;
|
||||
private TypeFactory typeFactory;
|
||||
private Types typeUtils;
|
||||
private Elements elementUtils;
|
||||
private TypeMirror javaLangObjectTypeMirror;
|
||||
|
||||
@Override
|
||||
public List<SourceMethod> process(ProcessorContext context, TypeElement mapperTypeElement, Void sourceModel) {
|
||||
this.messager = context.getMessager();
|
||||
this.typeFactory = context.getTypeFactory();
|
||||
this.typeUtils = context.getTypeUtils();
|
||||
this.elementUtils = context.getElementUtils();
|
||||
this.javaLangObjectTypeMirror = typeFactory.getType( Object.class ).getTypeMirror();
|
||||
return retrieveMethods( mapperTypeElement, mapperTypeElement );
|
||||
}
|
||||
|
||||
@ -88,11 +94,13 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
||||
List<SourceMethod> methods = new ArrayList<SourceMethod>();
|
||||
|
||||
for ( ExecutableElement executable : methodsIn( allEnclosingElementsIncludeSuper( usedMapper ) ) ) {
|
||||
if ( isNotObjectEquals( executable ) && wasNotYetOverridden( methods, executable ) ) {
|
||||
SourceMethod method = getMethod( usedMapper, executable, mapperToImplement );
|
||||
if ( method != null ) {
|
||||
methods.add( method );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Add all methods of used mappers in order to reference them in the aggregated model
|
||||
if ( usedMapper.equals( mapperToImplement ) ) {
|
||||
@ -111,6 +119,38 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
||||
return methods;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param executable the executable to check
|
||||
* @return <code>true</code>, iff the executable does not represent {@link java.lang.Object#equals(Object)} or an
|
||||
* overridden version of it
|
||||
*/
|
||||
private boolean isNotObjectEquals(ExecutableElement executable) {
|
||||
if ( "equals".equals( executable.getSimpleName().toString() )
|
||||
&& executable.getParameters().size() == 1
|
||||
&& executable.getParameters().get( 0 ).asType().equals( javaLangObjectTypeMirror ) ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param methods the list of already collected methods of one type hierarchy (order is from sub-types to
|
||||
* super-types)
|
||||
* @param executable the method to check
|
||||
* @return <code>true</code>, iff the given executable was not yet overridden by a method in the given list.
|
||||
*/
|
||||
private boolean wasNotYetOverridden(List<SourceMethod> methods, ExecutableElement executable) {
|
||||
for ( SourceMethod alreadyAdded : methods ) {
|
||||
ExecutableElement executableInSubtype = alreadyAdded.getExecutable();
|
||||
TypeElement declaringType = (TypeElement) executableInSubtype.getEnclosingElement();
|
||||
|
||||
if ( elementUtils.overrides( executableInSubtype, executable, declaringType ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private TypeElement asTypeElement(TypeMirror usedMapper) {
|
||||
return (TypeElement) ( (DeclaredType) usedMapper ).asElement();
|
||||
}
|
||||
|
@ -18,21 +18,24 @@
|
||||
*/
|
||||
package org.mapstruct.ap.test.abstractclass;
|
||||
|
||||
import static org.fest.assertions.Assertions.assertThat;
|
||||
|
||||
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.fest.assertions.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Test for the generation of implementation of abstract base classes.
|
||||
*
|
||||
* @author Gunnar Morling
|
||||
*/
|
||||
@WithClasses( { Source.class, Target.class, SourceTargetMapper.class, AbstractBaseMapper.class,
|
||||
BaseMapperInterface.class } )
|
||||
BaseMapperInterface.class,
|
||||
ReferencedMapper.class,
|
||||
AbstractReferencedMapper.class,
|
||||
ReferencedMapperInterface.class } )
|
||||
@RunWith( AnnotationProcessorTestRunner.class )
|
||||
public class AbstractClassTest {
|
||||
|
||||
@ -63,6 +66,8 @@ public class AbstractClassTest {
|
||||
private void assertResult(Target target) {
|
||||
assertThat( target ).isNotNull();
|
||||
assertThat( target.getSize() ).isEqualTo( Long.valueOf( 181 ) );
|
||||
assertThat( target.getBirthday() ).isEqualTo( "26.04.1948" );
|
||||
assertThat( target.getBirthday() ).isEqualTo( "Birthday: 26.04.1948" );
|
||||
assertThat( target.getManuallyConverted() ).isEqualTo( 42 );
|
||||
assertThat( target.isNotAttractingEqualsMethod() ).isTrue();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Copyright 2012-2014 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.abstractclass;
|
||||
|
||||
import javax.xml.ws.Holder;
|
||||
|
||||
/**
|
||||
* @author Andreas Gudian
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractReferencedMapper implements ReferencedMapperInterface {
|
||||
@Override
|
||||
public int holderToInt(Holder<String> holder) {
|
||||
return 41;
|
||||
}
|
||||
|
||||
public boolean objectToBoolean(Object obj) {
|
||||
if ( obj instanceof String ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return super.equals( obj );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode();
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Copyright 2012-2014 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.abstractclass;
|
||||
|
||||
import javax.xml.ws.Holder;
|
||||
|
||||
/**
|
||||
* @author Andreas Gudian
|
||||
*
|
||||
*/
|
||||
public class ReferencedMapper extends AbstractReferencedMapper {
|
||||
@Override
|
||||
public int holderToInt(Holder<String> holder) {
|
||||
return 42;
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Copyright 2012-2014 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.abstractclass;
|
||||
|
||||
import javax.xml.ws.Holder;
|
||||
|
||||
/**
|
||||
* @author Andreas Gudian
|
||||
*
|
||||
*/
|
||||
public interface ReferencedMapperInterface {
|
||||
int holderToInt(Holder<String> holder);
|
||||
}
|
@ -20,10 +20,14 @@ package org.mapstruct.ap.test.abstractclass;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
import javax.xml.ws.Holder;
|
||||
|
||||
public class Source {
|
||||
|
||||
private final int size;
|
||||
private final Calendar birthday;
|
||||
private final String notAttractingEqualsMethod = "no way";
|
||||
private final Holder<String> manuallyConverted = new Holder<String>("What is the answer?");
|
||||
|
||||
public Source() {
|
||||
size = 181;
|
||||
@ -38,4 +42,12 @@ public class Source {
|
||||
public Calendar getBirthday() {
|
||||
return birthday;
|
||||
}
|
||||
|
||||
public String getNotAttractingEqualsMethod() {
|
||||
return notAttractingEqualsMethod;
|
||||
}
|
||||
|
||||
public Holder<String> getManuallyConverted() {
|
||||
return manuallyConverted;
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ import java.util.Calendar;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper
|
||||
@Mapper( uses = ReferencedMapper.class )
|
||||
public abstract class SourceTargetMapper extends AbstractBaseMapper {
|
||||
|
||||
public static final SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class );
|
||||
@ -34,6 +34,6 @@ public abstract class SourceTargetMapper extends AbstractBaseMapper {
|
||||
|
||||
protected String calendarToString(Calendar calendar) {
|
||||
DateFormat format = new SimpleDateFormat( "dd.MM.yyyy" );
|
||||
return format.format( calendar.getTime() );
|
||||
return "Birthday: " + format.format( calendar.getTime() );
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,8 @@ public class Target {
|
||||
|
||||
private Long size;
|
||||
private String birthday;
|
||||
private boolean notAttractingEqualsMethod;
|
||||
private int manuallyConverted;
|
||||
|
||||
public Long getSize() {
|
||||
return size;
|
||||
@ -38,4 +40,20 @@ public class Target {
|
||||
public void setBirthday(String birthday) {
|
||||
this.birthday = birthday;
|
||||
}
|
||||
|
||||
public boolean isNotAttractingEqualsMethod() {
|
||||
return notAttractingEqualsMethod;
|
||||
}
|
||||
|
||||
public void setNotAttractingEqualsMethod(boolean notAttractingEqualsMethod) {
|
||||
this.notAttractingEqualsMethod = notAttractingEqualsMethod;
|
||||
}
|
||||
|
||||
public int getManuallyConverted() {
|
||||
return manuallyConverted;
|
||||
}
|
||||
|
||||
public void setManuallyConverted(int manuallyConverted) {
|
||||
this.manuallyConverted = manuallyConverted;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user