603 - Java 8 - Cant use static method on interface with decorators.

This commit is contained in:
Ivo Smid 2015-08-11 21:58:46 +02:00
parent e177f25d63
commit 60caf959e3
7 changed files with 226 additions and 5 deletions

View File

@ -0,0 +1,22 @@
/**
* Copyright 2012-2015 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._603;
public class Source {
}

View File

@ -0,0 +1,45 @@
/**
* Copyright 2012-2015 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._603;
import org.mapstruct.DecoratedWith;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
@Mapper
@DecoratedWith(SourceTargetMapperDecorator.class)
public interface SourceTargetMapper {
SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class );
@Mappings({
@Mapping(target = "value1", expression = "java( SourceTargetMapper.mapA() )"),
@Mapping(target = "value2", expression = "java( this.mapB() )")
})
Target mapSourceToTarget(Source source);
static String mapA() {
return "foo";
}
default String mapB() {
return "bar";
}
}

View File

@ -0,0 +1,33 @@
/**
* Copyright 2012-2015 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._603;
public abstract class SourceTargetMapperDecorator implements SourceTargetMapper {
private final SourceTargetMapper delegate;
protected SourceTargetMapperDecorator(SourceTargetMapper delegate) {
this.delegate = delegate;
}
@Override
public Target mapSourceToTarget(Source source) {
return delegate.mapSourceToTarget( source );
}
}

View File

@ -0,0 +1,40 @@
/**
* Copyright 2012-2015 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._603;
public class Target {
private String value1;
private String value2;
public String getValue1() {
return value1;
}
public void setValue1(String value1) {
this.value1 = value1;
}
public String getValue2() {
return value2;
}
public void setValue2(String value2) {
this.value2 = value2;
}
}

View File

@ -0,0 +1,39 @@
/**
* Copyright 2012-2015 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._603;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.fest.assertions.Assertions.assertThat;
public class Issue603Test {
@Test
public void shouldMapDataFromJava8Interface() {
final Source source = new Source();
final Target target = SourceTargetMapper.INSTANCE.mapSourceToTarget( source );
assertThat( target ).isNotNull();
assertThat( target.getValue1() ).isEqualTo( "foo" );
assertThat( target.getValue2() ).isEqualTo( "bar" );
}
}

View File

@ -238,7 +238,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.12.1</version>
<version>2.16</version>
<configuration>
<configLocation>build-config/checkstyle.xml</configLocation>
<consoleOutput>true</consoleOutput>
@ -252,7 +252,7 @@
specified as patterns within a source folder, so we can't exclude generated-sources
altogether
-->
<excludes>*Prism.java,*/itest/jaxb/xsd/*</excludes>
<excludes>**/*Prism.java,*/itest/jaxb/xsd/*</excludes>
</configuration>
<dependencies>
<dependency>
@ -270,7 +270,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<version>3.3</version>
<configuration>
<source>1.6</source>
<target>1.6</target>

View File

@ -18,9 +18,12 @@
*/
package org.mapstruct.ap.internal.util;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
@ -46,6 +49,19 @@ import static org.mapstruct.ap.internal.util.SpecificCompilerWorkarounds.replace
*/
public class Executables {
private static final Method DEFAULT_METHOD;
static {
Method method;
try {
method = ExecutableElement.class.getMethod( "isDefault" );
}
catch ( NoSuchMethodException e ) {
method = null;
}
DEFAULT_METHOD = method;
}
private static final AccessorNamingStrategy ACCESSOR_NAMING_STRATEGY = Services.get(
AccessorNamingStrategy.class,
new DefaultAccessorNamingStrategy()
@ -80,6 +96,18 @@ public class Executables {
return ACCESSOR_NAMING_STRATEGY.getPropertyName( getterOrSetterMethod );
}
public static boolean isDefaultMethod(ExecutableElement method) {
try {
return DEFAULT_METHOD != null && Boolean.TRUE.equals( DEFAULT_METHOD.invoke( method ) );
}
catch ( IllegalAccessException e ) {
return false;
}
catch ( InvocationTargetException e ) {
return false;
}
}
/**
* @param adderMethod the adder method
* @return the 'element name' to which an adder method applies. If. e.g. an adder method is named
@ -159,7 +187,9 @@ public class Executables {
List<ExecutableElement> methodsToAdd, TypeElement parentType) {
List<ExecutableElement> safeToAdd = new ArrayList<ExecutableElement>( methodsToAdd.size() );
for ( ExecutableElement toAdd : methodsToAdd ) {
if ( isNotObjectEquals( toAdd )
if ( isNotStaticMethodInInterface( toAdd, parentType )
&& isNotInterfaceDefaultMethod( toAdd, parentType )
&& isNotObjectEquals( toAdd )
&& wasNotYetOverridden( elementUtils, alreadyCollected, toAdd, parentType ) ) {
safeToAdd.add( toAdd );
}
@ -168,6 +198,18 @@ public class Executables {
alreadyCollected.addAll( 0, safeToAdd );
}
private static boolean isNotStaticMethodInInterface(ExecutableElement element, TypeElement parentType) {
return !( parentType.getKind().isInterface() &&
element.getKind() == ElementKind.METHOD &&
element.getModifiers().containsAll( Arrays.asList( Modifier.PUBLIC, Modifier.STATIC ) ) );
}
private static boolean isNotInterfaceDefaultMethod(ExecutableElement element, TypeElement parentType) {
return !( parentType.getKind().isInterface() &&
element.getKind() == ElementKind.METHOD &&
isDefaultMethod( element ) );
}
/**
* @param executable the executable to check
*