#103 keep defined accessibility modifier of mapper and mapping methods in the generated code

This commit is contained in:
Andreas Gudian 2014-02-16 22:26:31 +01:00
parent ace47f7e67
commit 8fe7a846c8
13 changed files with 290 additions and 6 deletions

View File

@ -23,11 +23,13 @@ import java.util.Collection;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
import javax.annotation.Generated;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import org.mapstruct.ap.model.common.Accessibility;
import org.mapstruct.ap.model.common.ModelElement;
import org.mapstruct.ap.model.common.Type;
import org.mapstruct.ap.model.common.TypeFactory;
@ -51,10 +53,12 @@ public class Mapper extends ModelElement {
private final List<MappingMethod> mappingMethods;
private final List<MapperReference> referencedMappers;
private final boolean suppressGeneratorTimestamp;
private final Accessibility accessibility;
private Mapper(TypeFactory typeFactory, String packageName, boolean superTypeIsInterface, String interfaceName,
String implementationName, List<MappingMethod> mappingMethods,
List<MapperReference> referencedMappers, boolean suppressGeneratorTimestamp) {
List<MapperReference> referencedMappers, boolean suppressGeneratorTimestamp,
Accessibility accessibility) {
this.packageName = packageName;
this.superTypeIsInterface = superTypeIsInterface;
this.interfaceName = interfaceName;
@ -64,6 +68,7 @@ public class Mapper extends ModelElement {
this.referencedMappers = referencedMappers;
this.suppressGeneratorTimestamp = suppressGeneratorTimestamp;
this.typeFactory = typeFactory;
this.accessibility = accessibility;
}
public static class Builder {
@ -114,7 +119,8 @@ public class Mapper extends ModelElement {
element.getSimpleName() + IMPLEMENTATION_SUFFIX,
mappingMethods,
mapperReferences,
suppressGeneratorTimestamp
suppressGeneratorTimestamp,
Accessibility.fromModifiers( element.getModifiers() )
);
}
}
@ -222,4 +228,8 @@ public class Mapper extends ModelElement {
public List<Annotation> getAnnotations() {
return annotations;
}
public Accessibility getAccessibility() {
return accessibility;
}
}

View File

@ -23,6 +23,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.mapstruct.ap.model.common.Accessibility;
import org.mapstruct.ap.model.common.ModelElement;
import org.mapstruct.ap.model.common.Parameter;
import org.mapstruct.ap.model.common.Type;
@ -40,12 +41,14 @@ public abstract class MappingMethod extends ModelElement {
private final List<Parameter> parameters;
private final Type returnType;
private final Parameter targetParameter;
private final Accessibility accessibility;
public MappingMethod(Method method) {
this.name = method.getName();
this.parameters = method.getParameters();
this.returnType = method.getReturnType();
this.targetParameter = method.getTargetParameter();
this.accessibility = method.getAccessibility();
}
public String getName() {
@ -81,6 +84,10 @@ public abstract class MappingMethod extends ModelElement {
return returnType;
}
public Accessibility getAccessibility() {
return accessibility;
}
public boolean isExistingInstanceMapping() {
return targetParameter != null;
}

View File

@ -0,0 +1,56 @@
/**
* 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.model.common;
import java.util.Set;
import javax.lang.model.element.Modifier;
/**
* Accessibility of an element
*
* @author Andreas Gudian
*/
public enum Accessibility {
PRIVATE( "private" ), DEFAULT( "" ), PROTECTED( "protected" ), PUBLIC( "public" );
private final String keyword;
private Accessibility(String keyword) {
this.keyword = keyword;
}
public String getKeyword() {
return keyword;
}
public static Accessibility fromModifiers(Set<Modifier> modifiers) {
if ( modifiers.contains( Modifier.PUBLIC ) ) {
return PUBLIC;
}
else if ( modifiers.contains( Modifier.PROTECTED ) ) {
return PROTECTED;
}
else if ( modifiers.contains( Modifier.PRIVATE ) ) {
return PRIVATE;
}
return DEFAULT;
}
}

View File

@ -22,9 +22,11 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import org.mapstruct.ap.model.common.Accessibility;
import org.mapstruct.ap.model.common.Parameter;
import org.mapstruct.ap.model.common.Type;
import org.mapstruct.ap.util.Strings;
@ -46,6 +48,7 @@ public class Method {
private final List<Parameter> parameters;
private final Parameter targetParameter;
private final Type returnType;
private final Accessibility accessibility;
private Map<String, List<Mapping>> mappings;
private IterableMapping iterableMapping;
@ -97,6 +100,7 @@ public class Method {
this.mappings = mappings;
this.iterableMapping = iterableMapping;
this.mapMapping = mapMapping;
this.accessibility = Accessibility.fromModifiers( executable.getModifiers() );
this.targetParameter = determineTargetParameter( parameters );
}
@ -163,6 +167,10 @@ public class Method {
return returnType;
}
public Accessibility getAccessibility() {
return accessibility;
}
public Map<String, List<Mapping>> getMappings() {
return mappings;
}

View File

@ -19,7 +19,7 @@
-->
@Override
public <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, </#if></#list>) {
<#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, </#if></#list>) {
if ( <#list sourceParameters as sourceParam>${sourceParam.name} == null<#if sourceParam_has_next> && </#if></#list> ) {
return<#if returnType.name != "void"> null</#if>;
}

View File

@ -19,7 +19,7 @@
-->
@Override
public <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, </#if></#list>) {
<#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, </#if></#list>) {
if ( ${sourceParameter.name} == null ) {
return<#if returnType.name != "void"> null</#if>;
}

View File

@ -19,7 +19,7 @@
-->
@Override
public <@includeModel object=returnType /> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, </#if></#list>) {
<#lt>${accessibility.keyword} <@includeModel object=returnType /> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, </#if></#list>) {
if ( ${sourceParameter.name} == null ) {
return<#if returnType.name != "void"> null</#if>;
}

View File

@ -31,7 +31,7 @@ import ${importedType.fullyQualifiedName};
<#list annotations as annotation>
<#nt><@includeModel object=annotation/>
</#list>
public class ${implementationName} <#if superTypeInterface>implements<#else>extends</#if> ${interfaceName} {
<#lt>${accessibility.keyword} class ${implementationName} <#if superTypeInterface>implements<#else>extends</#if> ${interfaceName} {
<#list referencedMappers as mapper>
<#nt> <@includeModel object=mapper/>

View File

@ -0,0 +1,71 @@
/**
* 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.accessibility;
import static java.lang.reflect.Modifier.isPrivate;
import static java.lang.reflect.Modifier.isProtected;
import static java.lang.reflect.Modifier.isPublic;
import static org.testng.Assert.assertTrue;
import org.mapstruct.ap.testutil.IssueKey;
import org.mapstruct.ap.testutil.MapperTestBase;
import org.mapstruct.ap.testutil.WithClasses;
import org.testng.annotations.Test;
/**
* Test for different accessibility modifiers
*
* @author Andreas Gudian
*/
@WithClasses( { Source.class, Target.class, DefaultSourceTargetMapperAbstr.class, DefaultSourceTargetMapperIfc.class } )
public class AccessibilityTest extends MapperTestBase {
@Test
@IssueKey( "103" )
public void testGeneratedModifiersFromAbstractClassAreCorrect() throws Exception {
Class<?> defaultFromAbstract = loadForMapper( DefaultSourceTargetMapperAbstr.class );
assertTrue( isDefault( defaultFromAbstract.getModifiers() ) );
assertTrue( isPublic( modifiersFor( defaultFromAbstract, "publicSourceToTarget" ) ) );
assertTrue( isProtected( modifiersFor( defaultFromAbstract, "protectedSourceToTarget" ) ) );
assertTrue( isDefault( modifiersFor( defaultFromAbstract, "defaultSourceToTarget" ) ) );
}
@Test
@IssueKey( "103" )
public void testGeneratedModifiersFromInterfaceAreCorrect() throws Exception {
Class<?> defaultFromIfc = loadForMapper( DefaultSourceTargetMapperIfc.class );
assertTrue( isDefault( defaultFromIfc.getModifiers() ) );
assertTrue( isPublic( modifiersFor( defaultFromIfc, "implicitlyPublicSoureToTarget" ) ) );
}
private static Class<?> loadForMapper(Class<?> mapper) throws ClassNotFoundException {
return Thread.currentThread().getContextClassLoader().loadClass( mapper.getName() + "Impl" );
}
private int modifiersFor(Class<?> clazz, String method) throws Exception {
return clazz.getDeclaredMethod( method, Source.class ).getModifiers();
}
private static boolean isDefault(int modifiers) {
return !isPublic( modifiers ) && !isProtected( modifiers ) && !isPrivate( modifiers );
}
}

View File

@ -0,0 +1,34 @@
/**
* 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.accessibility;
import org.mapstruct.Mapper;
/**
* @author Andreas Gudian
*
*/
@Mapper
abstract class DefaultSourceTargetMapperAbstr {
abstract Target defaultSourceToTarget(Source source);
protected abstract Target protectedSourceToTarget(Source source);
public abstract Target publicSourceToTarget(Source source);
}

View File

@ -0,0 +1,30 @@
/**
* 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.accessibility;
import org.mapstruct.Mapper;
/**
* @author Andreas Gudian
*
*/
@Mapper
interface DefaultSourceTargetMapperIfc {
Target implicitlyPublicSoureToTarget(Source source);
}

View File

@ -0,0 +1,34 @@
/**
* 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.accessibility;
/**
* @author Andreas Gudian
*/
public class Source {
private String foo;
public String getFoo() {
return foo;
}
public void setFoo(String foo) {
this.foo = foo;
}
}

View File

@ -0,0 +1,34 @@
/**
* 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.accessibility;
/**
* @author Andreas Gudian
*/
public class Target {
private String foo;
public String getFoo() {
return foo;
}
public void setFoo(String foo) {
this.foo = foo;
}
}