#198 fixing comments @agudian and applying throws clause to all MappingMethods

This commit is contained in:
sjaakd 2014-04-21 12:11:08 +02:00
parent 0ed14cd691
commit 51e33cb343
20 changed files with 259 additions and 36 deletions

View File

@ -39,7 +39,6 @@ public class BeanMappingMethod extends MappingMethod {
private final List<PropertyMapping> propertyMappings;
private final FactoryMethod factoryMethod;
private final List<Type> exceptionTypes;
public BeanMappingMethod(SourceMethod method,
List<PropertyMapping> propertyMappings,
@ -47,7 +46,6 @@ public class BeanMappingMethod extends MappingMethod {
super( method );
this.propertyMappings = propertyMappings;
this.factoryMethod = factoryMethod;
this.exceptionTypes = method.getExceptionTypes();
}
public List<PropertyMapping> getPropertyMappings() {
@ -83,8 +81,4 @@ public class BeanMappingMethod extends MappingMethod {
public FactoryMethod getFactoryMethod() {
return this.factoryMethod;
}
public List<Type> getExceptionTypes() {
return exceptionTypes;
}
}

View File

@ -42,6 +42,7 @@ public abstract class MappingMethod extends ModelElement {
private final Type returnType;
private final Parameter targetParameter;
private final Accessibility accessibility;
private final List<Type> thrownTypes;
protected MappingMethod(Method method) {
this.name = method.getName();
@ -49,6 +50,7 @@ public abstract class MappingMethod extends ModelElement {
this.returnType = method.getReturnType();
this.targetParameter = method.getTargetParameter();
this.accessibility = method.getAccessibility();
this.thrownTypes = method.getThrownTypes();
}
public String getName() {
@ -102,7 +104,7 @@ public abstract class MappingMethod extends ModelElement {
types.add( getReturnType() );
types.addAll( getReturnType().getImportTypes() );
types.addAll( thrownTypes );
return types;
}
@ -116,6 +118,10 @@ public abstract class MappingMethod extends ModelElement {
return parameterNames;
}
public List<Type> getThrownTypes() {
return thrownTypes;
}
@Override
public String toString() {
return returnType + " " + getName() + "(" + Strings.join( parameters, ", " ) + ")";

View File

@ -18,6 +18,7 @@
*/
package org.mapstruct.ap.model.assignment;
import java.util.ArrayList;
import java.util.List;
import org.mapstruct.ap.model.Assignment;
import org.mapstruct.ap.model.common.Type;
@ -38,9 +39,14 @@ public class LocalVarWrapper extends AssignmentWrapper {
@Override
public List<Type> getExceptionTypes() {
List<Type> result = super.getExceptionTypes();
for (Type exceptionTypeToExclude : exceptionTypesToExclude) {
result.remove( exceptionTypeToExclude );
List<Type> parentExceptionTypes = super.getExceptionTypes();
List<Type> result = new ArrayList<Type>( parentExceptionTypes );
for ( Type exceptionTypeToExclude : exceptionTypesToExclude ) {
for ( Type parentExceptionType : parentExceptionTypes ) {
if ( parentExceptionType.isAssignableTo( exceptionTypeToExclude ) ) {
result.remove( parentExceptionType );
}
}
}
return result;
}

View File

@ -20,6 +20,7 @@ package org.mapstruct.ap.model.assignment;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.mapstruct.ap.model.Assignment;
@ -73,10 +74,12 @@ public class MethodReference extends MappingMethod implements Assignment, Factor
super( method );
this.declaringMapper = declaringMapper;
this.contextParam = null;
this.importTypes = targetType == null ?
Collections.<Type>emptySet() :
Collections.<Type>singleton( targetType );
this.exceptionTypes = method.getExceptionTypes();
Set<Type> imported = new HashSet( method.getThrownTypes() );
if ( targetType != null ) {
imported.add( targetType );
}
this.importTypes = Collections.<Type>unmodifiableSet( imported );
this.exceptionTypes = method.getThrownTypes();
}
public MethodReference(BuiltInMethod method, ConversionContext contextParam) {

View File

@ -18,6 +18,7 @@
*/
package org.mapstruct.ap.model.assignment;
import java.util.ArrayList;
import java.util.List;
import org.mapstruct.ap.model.Assignment;
import org.mapstruct.ap.model.common.Type;
@ -38,10 +39,16 @@ public class SetterWrapper extends AssignmentWrapper {
@Override
public List<Type> getExceptionTypes() {
List<Type> result = super.getExceptionTypes();
for (Type exceptionTypeToExclude : exceptionTypesToExclude) {
result.remove( exceptionTypeToExclude );
List<Type> parentExceptionTypes = super.getExceptionTypes();
List<Type> result = new ArrayList<Type>( parentExceptionTypes );
for ( Type exceptionTypeToExclude : exceptionTypesToExclude ) {
for ( Type parentExceptionType : parentExceptionTypes ) {
if ( parentExceptionType.isAssignableTo( exceptionTypeToExclude ) ) {
result.remove( parentExceptionType );
}
}
}
return result;
}
}

View File

@ -96,4 +96,11 @@ public interface Method {
* @return return type
*/
Type getReturnType();
/**
* Returns all exceptions thrown by this method
*
* @return exceptions thrown
*/
List<Type> getThrownTypes();
}

View File

@ -351,7 +351,7 @@ public class SourceMethod implements Method {
return false;
}
public List<Type> getExceptionTypes() {
public List<Type> getThrownTypes() {
return exceptionTypes;
}
}

View File

@ -177,4 +177,9 @@ public abstract class BuiltInMethod implements Method {
public Accessibility getAccessibility() {
return Accessibility.PRIVATE;
}
@Override
public List<Type> getThrownTypes() {
return Collections.emptyList();
}
}

View File

@ -670,7 +670,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
}
// target accessor is setter, so decorate assigmment as setter
assignment = new SetterWrapper( assignment, method.getExceptionTypes() );
assignment = new SetterWrapper( assignment, method.getThrownTypes() );
// decorate assigment with null check of source can be null (is not primitive)
if ( !sourceType.isPrimitive() ) {
@ -736,7 +736,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
}
// target accessor is setter, so decorate assigmment as setter
assignment = new SetterWrapper( assignment, method.getExceptionTypes() );
assignment = new SetterWrapper( assignment, method.getThrownTypes() );
FactoryMethod factoryMethod = getFactoryMethod( mapperReferences, methods, method.getReturnType() );
return new IterableMappingMethod( method, assignment, factoryMethod );
@ -807,8 +807,8 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
FactoryMethod factoryMethod = getFactoryMethod( mapperReferences, methods, method.getReturnType() );
keyAssignment = new LocalVarWrapper( keyAssignment, method.getExceptionTypes() );
valueAssignment = new LocalVarWrapper( valueAssignment, method.getExceptionTypes() );
keyAssignment = new LocalVarWrapper( keyAssignment, method.getThrownTypes() );
valueAssignment = new LocalVarWrapper( valueAssignment, method.getThrownTypes() );
return new MapMappingMethod( method, keyAssignment, valueAssignment, factoryMethod );
}

View File

@ -19,7 +19,7 @@
-->
@Override
<#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, </#if></#list>)<@exceptions/> {
<#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, </#if></#list>) <@throws/> {
if ( <#list sourceParameters as sourceParam>${sourceParam.name} == null<#if sourceParam_has_next> && </#if></#list> ) {
return<#if returnType.name != "void"> null</#if>;
}
@ -43,4 +43,12 @@
return ${resultName};
</#if>
}
<#macro exceptions><#if (exceptionTypes?size > 0)> throws </#if><#list exceptionTypes as exceptionType>${exceptionType.name}<#if exceptionType_has_next>, </#if></#list></#macro>
<#macro throws>
<@compress single_line=true>
<#if (thrownTypes?size > 0)>throws </#if>
<#list thrownTypes as exceptionType>
<@includeModel object=exceptionType/>
<#if exceptionType_has_next>, </#if>
</#list>
</@compress>
</#macro>

View File

@ -19,6 +19,15 @@
-->
@Override
public <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, </#if></#list>) {
public <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, </#if></#list>) <@throws/> {
return delegate.${name}( <#list parameters as param>${param.name}<#if param_has_next>, </#if></#list> );
}
}
<#macro throws>
<@compress single_line=true>
<#if (thrownTypes?size > 0)>throws </#if>
<#list thrownTypes as exceptionType>
<@includeModel object=exceptionType/>
<#if exceptionType_has_next>, </#if>
</#list>
</@compress>
</#macro>

View File

@ -19,7 +19,7 @@
-->
@Override
<#lt>${accessibility.keyword} <@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>) <@throws/> {
if ( ${sourceParameter.name} == null ) {
return<#if returnType.name != "void"> null</#if>;
}
@ -38,4 +38,13 @@
return ${resultName};
</#if>
}
}
<#macro throws>
<@compress single_line=true>
<#if (thrownTypes?size > 0)>throws </#if>
<#list thrownTypes as exceptionType>
<@includeModel object=exceptionType/>
<#if exceptionType_has_next>, </#if>
</#list>
</@compress>
</#macro>

View File

@ -19,7 +19,7 @@
-->
@Override
<#lt>${accessibility.keyword} <@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>) <@throws/> {
if ( ${sourceParameter.name} == null ) {
return<#if returnType.name != "void"> null</#if>;
}
@ -53,3 +53,12 @@
<#local result><@includeModel object=type/></#local>
<#return result>
</#function>
<#macro throws>
<@compress single_line=true>
<#if (thrownTypes?size > 0)>throws </#if>
<#list thrownTypes as exceptionType>
<@includeModel object=exceptionType/>
<#if exceptionType_has_next>, </#if>
</#list>
</@compress>
</#macro>

View File

@ -18,7 +18,12 @@
*/
package org.mapstruct.ap.test.exceptions;
import org.mapstruct.ap.test.exceptions.imports.TestException1;
import org.mapstruct.ap.test.exceptions.imports.TestExceptionBase;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mapstruct.ap.testutil.IssueKey;
@ -34,27 +39,101 @@ import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
Target.class,
SourceTargetMapper.class,
ExceptionTestMapper.class,
ExceptionTestDecorator.class,
TestExceptionBase.class,
TestException1.class,
TestException2.class } )
@RunWith( AnnotationProcessorTestRunner.class )
public class ExceptionTest {
@Test(expected = RuntimeException.class)
@Test( expected = RuntimeException.class )
@IssueKey( "198" )
public void shouldThrowRuntime() throws TestException2 {
public void shouldThrowRuntimeInBeanMapping() throws TestException2 {
Source source = new Source();
source.setSize( 1 );
SourceTargetMapper sourceTargetMapper = SourceTargetMapper.INSTANCE;
sourceTargetMapper.sourceToTarget( source );
}
@Test(expected = TestException2.class)
@Test( expected = TestException2.class )
@IssueKey( "198" )
public void shouldThrowTestException2() throws TestException2 {
public void shouldThrowTestException2InBeanMapping() throws TestException2 {
Source source = new Source();
source.setSize( 2 );
SourceTargetMapper sourceTargetMapper = SourceTargetMapper.INSTANCE;
sourceTargetMapper.sourceToTarget( source );
}
@Test( expected = RuntimeException.class )
@IssueKey( "198" )
public void shouldThrowRuntimeInIterableMapping() throws TestException2 {
List<Integer> source = new ArrayList<Integer>();
source.add( 1 );
SourceTargetMapper sourceTargetMapper = SourceTargetMapper.INSTANCE;
sourceTargetMapper.integerListToLongList( source );
}
@Test( expected = TestException2.class )
@IssueKey( "198" )
public void shouldThrowTestException2InIterableMapping() throws TestException2 {
List<Integer> source = new ArrayList<Integer>();
source.add( 2 );
SourceTargetMapper sourceTargetMapper = SourceTargetMapper.INSTANCE;
sourceTargetMapper.integerListToLongList( source );
}
@Test( expected = RuntimeException.class )
@IssueKey( "198" )
public void shouldThrowRuntimeInMapKeyMapping() throws TestException2 {
Map<Integer, String> source = new HashMap<Integer, String>();
source.put( 1, "test" );
SourceTargetMapper sourceTargetMapper = SourceTargetMapper.INSTANCE;
sourceTargetMapper.integerKeyMapToLongKeyMap( source );
}
@Test( expected = TestException2.class )
@IssueKey( "198" )
public void shouldThrowTestException2InMapKeyMapping() throws TestException2 {
Map<Integer, String> source = new HashMap<Integer, String>();
source.put( 2, "test" );
SourceTargetMapper sourceTargetMapper = SourceTargetMapper.INSTANCE;
sourceTargetMapper.integerKeyMapToLongKeyMap( source );
}
@Test( expected = RuntimeException.class )
@IssueKey( "198" )
public void shouldThrowRuntimeInMapValueMapping() throws TestException2 {
Map<String, Integer> source = new HashMap<String, Integer>();
source.put( "test", 1 );
SourceTargetMapper sourceTargetMapper = SourceTargetMapper.INSTANCE;
sourceTargetMapper.integerValueMapToLongValueMap( source );
}
@Test( expected = TestException2.class )
@IssueKey( "198" )
public void shouldThrowTestException2InMapValueMapping() throws TestException2 {
Map<String, Integer> source = new HashMap<String, Integer>();
source.put( "test", 2 );
SourceTargetMapper sourceTargetMapper = SourceTargetMapper.INSTANCE;
sourceTargetMapper.integerValueMapToLongValueMap( source );
}
@Test( expected = RuntimeException.class )
@IssueKey( "198" )
public void shouldThrowRuntimeInBeanMappingViaBaseException() throws TestExceptionBase {
Source source = new Source();
source.setSize( 1 );
SourceTargetMapper sourceTargetMapper = SourceTargetMapper.INSTANCE;
sourceTargetMapper.sourceToTargetViaBaseException( source );
}
@Test( expected = TestException2.class )
@IssueKey( "198" )
public void shouldThrowTestException2InBeanMappingViaBaseException() throws TestExceptionBase {
Source source = new Source();
source.setSize( 2 );
SourceTargetMapper sourceTargetMapper = SourceTargetMapper.INSTANCE;
sourceTargetMapper.sourceToTargetViaBaseException( source );
}
}

View File

@ -0,0 +1,28 @@
/**
* 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.exceptions;
public abstract class ExceptionTestDecorator implements SourceTargetMapper {
private final SourceTargetMapper delegate;
public ExceptionTestDecorator(SourceTargetMapper delegate) {
this.delegate = delegate;
}
}

View File

@ -18,6 +18,8 @@
*/
package org.mapstruct.ap.test.exceptions;
import org.mapstruct.ap.test.exceptions.imports.TestException1;
/**
* @author Sjaak Derksen
*
@ -33,4 +35,14 @@ public class ExceptionTestMapper {
}
return new Long(size);
}
public Long toLong(Integer size) throws TestException1, TestException2 {
if ( size == 1 ) {
throw new TestException1();
}
else if ( size == 2 ) {
throw new TestException2();
}
return new Long(size);
}
}

View File

@ -19,6 +19,10 @@
package org.mapstruct.ap.test.exceptions;
import org.mapstruct.ap.test.exceptions.imports.TestExceptionBase;
import java.util.List;
import java.util.Map;
import org.mapstruct.DecoratedWith;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@ -27,10 +31,19 @@ import org.mapstruct.factory.Mappers;
* @author Sjaak Derksen
*/
@Mapper( uses = ExceptionTestMapper.class )
@DecoratedWith( ExceptionTestDecorator.class )
public interface SourceTargetMapper {
SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class );
Target sourceToTarget(Source source) throws TestException2;
List<Long> integerListToLongList(List<Integer> sizes) throws TestException2;
Map<Long, String> integerKeyMapToLongKeyMap(Map<Integer, String> sizes) throws TestException2;
Map<String, Long> integerValueMapToLongValueMap(Map<String, Integer> sizes) throws TestException2;
Target sourceToTargetViaBaseException(Source source) throws TestExceptionBase;
}

View File

@ -18,9 +18,11 @@
*/
package org.mapstruct.ap.test.exceptions;
import org.mapstruct.ap.test.exceptions.imports.TestExceptionBase;
/**
*
* @author Sjaak Derksen
*/
public class TestException2 extends Exception {
public class TestException2 extends TestExceptionBase {
}

View File

@ -16,7 +16,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mapstruct.ap.test.exceptions;
package org.mapstruct.ap.test.exceptions.imports;
/**
*

View File

@ -0,0 +1,26 @@
/**
* 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.exceptions.imports;
/**
*
* @author Sjaak Derksen
*/
public class TestExceptionBase extends Exception {
}