#200 renaming Decorator to Wrapper, Adding Javadoc, Factory to FactoryMethod, cleanup

This commit is contained in:
sjaakd 2014-04-15 21:42:23 +02:00
parent d412fd3e83
commit 3e7e2e0443
22 changed files with 126 additions and 73 deletions

View File

@ -22,19 +22,49 @@ import java.util.Set;
import org.mapstruct.ap.model.common.Type;
/**
* Assignment represents all kind of manners a source can be assigned to a target.
*
* @author Sjaak Derksen
*/
public interface Assignment {
/**
* returns all types required as import by the assignment statement.
*
* @return imported types
*/
Set<Type> getImportTypes();
/**
* returns all types exception types thrown by this assignment.
*
* @return exceptions thrown
*/
Set<Type> getExceptionTypes();
/**
* An assignment in itself can wrap another assignment. E.g.:
* <ul>
* <li>a MethodReference can wrap a TypeConversion, another MethodReference and ultimately a Simple</li>
* <li>a TypeConversion can wrap a MethodReference, and ultimately a Simple</li>
* </ul>
*
* @param assignment
*/
void setAssignment( Assignment assignment );
/**
* the source reference being a source-getter, a constant, etc.
*
* @return source reference
*/
String getSourceReference();
// TODO: tempfix..
/**
* Returns whether the implemented assignment is a plain source assignment (Simple assignment)
* (so not a MethodReference or TypeConversion).
*
* @return true when this is a (wrapped) Simple Assignment
*/
boolean isSimple();
}

View File

@ -38,11 +38,11 @@ import org.mapstruct.ap.model.source.SourceMethod;
public class BeanMappingMethod extends MappingMethod {
private final List<PropertyMapping> propertyMappings;
private final Factory factoryMethod;
private final FactoryMethod factoryMethod;
public BeanMappingMethod(SourceMethod method,
List<PropertyMapping> propertyMappings,
Factory factoryMethod) {
FactoryMethod factoryMethod) {
super( method );
this.propertyMappings = propertyMappings;
this.factoryMethod = factoryMethod;
@ -78,7 +78,7 @@ public class BeanMappingMethod extends MappingMethod {
return types;
}
public Factory getFactoryMethod() {
public FactoryMethod getFactoryMethod() {
return this.factoryMethod;
}

View File

@ -22,10 +22,11 @@ import java.util.Set;
import org.mapstruct.ap.model.common.Type;
/**
* FactoryMethod, implemented in referenced mapper.
*
* @author Sjaak Derksen
*/
public interface Factory {
public interface FactoryMethod {
Set<Type> getExceptionTypes();

View File

@ -34,9 +34,9 @@ import org.mapstruct.ap.util.Strings;
public class IterableMappingMethod extends MappingMethod {
private final Assignment elementAssignment;
private final Factory factoryMethod;
private final FactoryMethod factoryMethod;
public IterableMappingMethod(SourceMethod method, Assignment parameterAssignment, Factory factoryMethod) {
public IterableMappingMethod(SourceMethod method, Assignment parameterAssignment, FactoryMethod factoryMethod) {
super( method );
this.elementAssignment = parameterAssignment;
this.factoryMethod = factoryMethod;
@ -74,7 +74,7 @@ public class IterableMappingMethod extends MappingMethod {
);
}
public Factory getFactoryMethod() {
public FactoryMethod getFactoryMethod() {
return this.factoryMethod;
}
}

View File

@ -35,10 +35,10 @@ public class MapMappingMethod extends MappingMethod {
private final Assignment keyAssignment;
private final Assignment valueAssignment;
private final Factory factoryMethod;
private final FactoryMethod factoryMethod;
public MapMappingMethod(SourceMethod method, Assignment keyAssignment, Assignment valueAssignment,
Factory factoryMethod) {
FactoryMethod factoryMethod) {
super( method );
this.keyAssignment = keyAssignment;
@ -99,7 +99,7 @@ public class MapMappingMethod extends MappingMethod {
);
}
public Factory getFactoryMethod() {
public FactoryMethod getFactoryMethod() {
return this.factoryMethod;
}

View File

@ -18,10 +18,9 @@
*/
package org.mapstruct.ap.model.assignment;
import java.util.Collections;
import java.util.Set;
import org.mapstruct.ap.model.Assignment;
import org.mapstruct.ap.model.Factory;
import org.mapstruct.ap.model.FactoryMethod;
import org.mapstruct.ap.model.MapperReference;
import org.mapstruct.ap.model.common.ConversionContext;
import org.mapstruct.ap.model.common.Type;
@ -29,6 +28,7 @@ import org.mapstruct.ap.model.source.SourceMethod;
import org.mapstruct.ap.model.source.builtin.BuiltInMethod;
/**
* Factory class for creating all types of assignments
*
* @author Sjaak Derksen
*/
@ -44,27 +44,21 @@ public class AssignmentFactory {
return new TypeConversion( importTypes, exceptionTypes, openExpression, closeExpression );
}
public static Assignment createTypeConversion( String openExpression, String closeExpression ) {
return new TypeConversion( Collections.<Type>emptySet(),
Collections.<Type>emptySet(),
openExpression,
closeExpression );
}
public static Factory createFactory(SourceMethod method, MapperReference declaringMapper) {
public static FactoryMethod createFactory(SourceMethod method, MapperReference declaringMapper) {
return new MethodReference( method, declaringMapper, null );
}
public static Assignment createAssignment(SourceMethod method, MapperReference declaringMapper, Type targetType) {
public static Assignment createMethodReference(SourceMethod method, MapperReference declaringMapper,
Type targetType) {
return new MethodReference(method, declaringMapper, targetType);
}
public static Assignment createAssignment( BuiltInMethod method, ConversionContext contextParam ) {
public static Assignment createMethodReference( BuiltInMethod method, ConversionContext contextParam ) {
return new MethodReference( method, contextParam );
}
public static SimpleAssignment createAssignment( String sourceRef ) {
return new SimpleAssignment(sourceRef );
public static Simple createSimple( String sourceRef ) {
return new Simple(sourceRef );
}
}

View File

@ -24,14 +24,15 @@ import org.mapstruct.ap.model.common.ModelElement;
import org.mapstruct.ap.model.common.Type;
/**
* Base class for decorators (wrappers). Decorator pattern is used to decorate assignments.
*
* @author Sjaak Derksen
*/
public abstract class AssignmentDecorator extends ModelElement implements Assignment {
public abstract class AssignmentWrapper extends ModelElement implements Assignment {
private final Assignment decoratedAssignment;
public AssignmentDecorator( Assignment decoratedAssignment ) {
public AssignmentWrapper( Assignment decoratedAssignment ) {
this.decoratedAssignment = decoratedAssignment;
}
@ -47,7 +48,7 @@ public abstract class AssignmentDecorator extends ModelElement implements Assign
@Override
public void setAssignment( Assignment assignment ) {
decoratedAssignment.setAssignment( assignment );
throw new UnsupportedOperationException("deliberately not implemented");
}
public Assignment getAssignment() {

View File

@ -21,12 +21,13 @@ package org.mapstruct.ap.model.assignment;
import org.mapstruct.ap.model.Assignment;
/**
* Decorates an assignment as local variable.
*
* @author Sjaak Derksen
*/
public class LocalVarDecorator extends AssignmentDecorator {
public class LocalVarWrapper extends AssignmentWrapper {
public LocalVarDecorator( Assignment decoratedAssignment ) {
public LocalVarWrapper( Assignment decoratedAssignment ) {
super( decoratedAssignment );
}
}

View File

@ -22,7 +22,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.mapstruct.ap.model.Assignment;
import org.mapstruct.ap.model.Factory;
import org.mapstruct.ap.model.FactoryMethod;
import org.mapstruct.ap.model.MapperReference;
import org.mapstruct.ap.model.MappingMethod;
@ -37,7 +37,7 @@ import org.mapstruct.ap.model.source.builtin.BuiltInMethod;
*
* @author Gunnar Morling
*/
public class MethodReference extends MappingMethod implements Assignment, Factory {
public class MethodReference extends MappingMethod implements Assignment, FactoryMethod {
private final MapperReference declaringMapper;
private final Set<Type> importTypes;
@ -121,8 +121,7 @@ public class MethodReference extends MappingMethod implements Assignment, Factor
@Override
public Set<Type> getImportTypes() {
Set<Type> imported = new HashSet(super.getImportTypes());
imported.addAll( importTypes );
Set<Type> imported = org.mapstruct.ap.util.Collections.asSet( importTypes, super.getImportTypes() );
if ( assignment != null ) {
imported.addAll( assignment.getImportTypes() );
}

View File

@ -21,12 +21,13 @@ package org.mapstruct.ap.model.assignment;
import org.mapstruct.ap.model.Assignment;
/**
* Decorates the assignment as a Map or Collection constructor
*
* @author Sjaak Derksen
*/
public class NewCollectionOrMapDecorator extends AssignmentDecorator {
public class NewCollectionOrMapWrapper extends AssignmentWrapper {
public NewCollectionOrMapDecorator( Assignment decoratedAssignment ) {
public NewCollectionOrMapWrapper( Assignment decoratedAssignment ) {
super( decoratedAssignment );
}
}

View File

@ -21,12 +21,13 @@ package org.mapstruct.ap.model.assignment;
import org.mapstruct.ap.model.Assignment;
/**
* Wraps the assignment in a null check.
*
* @author Sjaak Derksen
*/
public class NullCheckDecorator extends AssignmentDecorator {
public class NullCheckWrapper extends AssignmentWrapper {
public NullCheckDecorator( Assignment decoratedAssignment ) {
public NullCheckWrapper( Assignment decoratedAssignment ) {
super( decoratedAssignment );
}
}

View File

@ -21,12 +21,13 @@ package org.mapstruct.ap.model.assignment;
import org.mapstruct.ap.model.Assignment;
/**
* Wraps the assignment in a target setter.
*
* @author Sjaak Derksen
*/
public class SetterDecorator extends AssignmentDecorator {
public class SetterWrapper extends AssignmentWrapper {
public SetterDecorator( Assignment decoratedAssignment ) {
public SetterWrapper( Assignment decoratedAssignment ) {
super( decoratedAssignment );
}
}

View File

@ -25,14 +25,15 @@ import org.mapstruct.ap.model.common.ModelElement;
import org.mapstruct.ap.model.common.Type;
/**
* Simple Assignment. Just a source reference
*
* @author Sjaak Derksen
*/
public class SimpleAssignment extends ModelElement implements Assignment {
public class Simple extends ModelElement implements Assignment {
private final String sourceReference;
public SimpleAssignment( String sourceReference ) {
public Simple( String sourceReference ) {
this.sourceReference = sourceReference;
}

View File

@ -18,7 +18,14 @@
*/
/**
* <p>
* Meta-model of assignments
* Meta-model of assignments. There are currently three types of assignment
* <ul>
* <li>Simple</li>
* <li>TypeConversion</li>
* <li>MethodReference</li>
*
* The assignments can be wrapped. E.g. in a collection or map constructor, a null check, a try-catch, etc.
* </ul>
* </p>
*/
package org.mapstruct.ap.model.assignment;

View File

@ -43,7 +43,7 @@ import org.mapstruct.ap.model.Decorator;
import org.mapstruct.ap.model.DefaultMapperReference;
import org.mapstruct.ap.model.DelegatingMethod;
import org.mapstruct.ap.model.EnumMappingMethod;
import org.mapstruct.ap.model.Factory;
import org.mapstruct.ap.model.FactoryMethod;
import org.mapstruct.ap.model.IterableMappingMethod;
import org.mapstruct.ap.model.MapMappingMethod;
import org.mapstruct.ap.model.Mapper;
@ -51,10 +51,10 @@ import org.mapstruct.ap.model.MapperReference;
import org.mapstruct.ap.model.MappingMethod;
import org.mapstruct.ap.model.PropertyMapping;
import org.mapstruct.ap.model.assignment.AssignmentFactory;
import org.mapstruct.ap.model.assignment.NewCollectionOrMapDecorator;
import org.mapstruct.ap.model.assignment.LocalVarDecorator;
import org.mapstruct.ap.model.assignment.NullCheckDecorator;
import org.mapstruct.ap.model.assignment.SetterDecorator;
import org.mapstruct.ap.model.assignment.NewCollectionOrMapWrapper;
import org.mapstruct.ap.model.assignment.LocalVarWrapper;
import org.mapstruct.ap.model.assignment.NullCheckWrapper;
import org.mapstruct.ap.model.assignment.SetterWrapper;
import org.mapstruct.ap.model.common.Parameter;
import org.mapstruct.ap.model.common.Type;
import org.mapstruct.ap.model.common.TypeFactory;
@ -321,9 +321,9 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
return mappingMethods;
}
private Factory getFactoryMethod(List<MapperReference> mapperReferences, List<SourceMethod> methods,
private FactoryMethod getFactoryMethod(List<MapperReference> mapperReferences, List<SourceMethod> methods,
Type returnType) {
Factory result = null;
FactoryMethod result = null;
for ( SourceMethod method : methods ) {
if ( !method.requiresImplementation() && !method.isIterableMapping() && !method.isMapMapping()
&& method.getSourceParameters().size() == 0 ) {
@ -493,7 +493,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
mappedTargetProperties
);
Factory factoryMethod = getFactoryMethod( mapperReferences, methods, method.getReturnType() );
FactoryMethod factoryMethod = getFactoryMethod( mapperReferences, methods, method.getReturnType() );
return new BeanMappingMethod( method, propertyMappings, factoryMethod );
}
@ -662,22 +662,21 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
if ( assignment != null ) {
// target accessor is setter, so decorate assigmment as setter
assignment = new SetterDecorator( assignment );
// create a new Map or Collection implementation if no method or type conversion
if ( targetType != null && ( targetType.isCollectionType() || targetType.isMapType() ) ) {
if ( assignment.isSimple() ) {
assignment = new NewCollectionOrMapDecorator( assignment );
assignment = new NewCollectionOrMapWrapper( assignment );
}
}
// target accessor is setter, so decorate assigmment as setter
assignment = new SetterWrapper( assignment );
// decorate assigment with null check of source can be null (is not primitive)
if ( !sourceType.isPrimitive() ) {
assignment = new NullCheckDecorator( assignment );
assignment = new NullCheckWrapper( assignment );
}
}
else {
messager.printMessage(
@ -737,9 +736,9 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
}
// target accessor is setter, so decorate assigmment as setter
assignment = new SetterDecorator( assignment );
assignment = new SetterWrapper( assignment );
Factory factoryMethod = getFactoryMethod( mapperReferences, methods, method.getReturnType() );
FactoryMethod factoryMethod = getFactoryMethod( mapperReferences, methods, method.getReturnType() );
return new IterableMappingMethod( method, assignment, factoryMethod );
}
@ -806,10 +805,10 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
);
}
Factory factoryMethod = getFactoryMethod( mapperReferences, methods, method.getReturnType() );
FactoryMethod factoryMethod = getFactoryMethod( mapperReferences, methods, method.getReturnType() );
keyAssignment = new LocalVarDecorator( keyAssignment );
valueAssignment = new LocalVarDecorator( valueAssignment );
keyAssignment = new LocalVarWrapper( keyAssignment );
valueAssignment = new LocalVarWrapper( valueAssignment );
return new MapMappingMethod( method, keyAssignment, valueAssignment, factoryMethod );
}

View File

@ -32,7 +32,7 @@ import org.mapstruct.ap.conversion.ConversionProvider;
import org.mapstruct.ap.conversion.Conversions;
import org.mapstruct.ap.model.Assignment;
import org.mapstruct.ap.model.MapperReference;
import org.mapstruct.ap.model.assignment.SimpleAssignment;
import org.mapstruct.ap.model.assignment.Simple;
import org.mapstruct.ap.model.VirtualMappingMethod;
import org.mapstruct.ap.model.assignment.AssignmentFactory;
import org.mapstruct.ap.model.common.ConversionContext;
@ -182,21 +182,21 @@ public class MappingResolver {
// first simpele mapping method
Assignment referencedMethod = resolveViaMethod( sourceType, targetType );
if ( referencedMethod != null ) {
referencedMethod.setAssignment( AssignmentFactory.createAssignment( sourceReference ) );
referencedMethod.setAssignment( AssignmentFactory.createSimple( sourceReference ) );
context.virtualMethods.addAll( virtualMethodCandidates );
return referencedMethod;
}
// then direct assignable
if ( sourceType.isAssignableTo( targetType ) || context.isPropertyMappable( sourceType, targetType ) ) {
SimpleAssignment simpleAssignment = AssignmentFactory.createAssignment( sourceReference );
Simple simpleAssignment = AssignmentFactory.createSimple( sourceReference );
return simpleAssignment;
}
// then type conversion
Assignment conversion = resolveViaConversion( sourceType, targetType );
if ( conversion != null ) {
conversion.setAssignment( AssignmentFactory.createAssignment( sourceReference) );
conversion.setAssignment( AssignmentFactory.createSimple( sourceReference) );
return conversion;
}
@ -259,8 +259,8 @@ public class MappingResolver {
if ( matchingBuiltInMethod != null ) {
virtualMethodCandidates.add( new VirtualMappingMethod( matchingBuiltInMethod ) );
ConversionContext ctx = new DefaultConversionContext( context.typeFactory, targetType, dateFormat );
Assignment methodReference = AssignmentFactory.createAssignment( matchingBuiltInMethod, ctx );
methodReference.setAssignment( AssignmentFactory.createAssignment( sourceReference ) );
Assignment methodReference = AssignmentFactory.createMethodReference( matchingBuiltInMethod, ctx );
methodReference.setAssignment( AssignmentFactory.createSimple( sourceReference ) );
return methodReference;
}
@ -301,7 +301,7 @@ public class MappingResolver {
);
if ( methodRefX != null ) {
methodRefY.setAssignment( methodRefX );
methodRefX.setAssignment( AssignmentFactory.createAssignment( sourceReference ) );
methodRefX.setAssignment( AssignmentFactory.createSimple( sourceReference ) );
break;
}
else {
@ -343,7 +343,7 @@ public class MappingResolver {
);
if ( conversionXRef != null ) {
methodRefY.setAssignment( conversionXRef );
conversionXRef.setAssignment( new SimpleAssignment( sourceReference ) );
conversionXRef.setAssignment( new Simple( sourceReference ) );
break;
}
else {
@ -383,7 +383,7 @@ public class MappingResolver {
conversionYRef = resolveViaConversion( methodXCandidate.getReturnType(), targetType );
if ( conversionYRef != null ) {
conversionYRef.setAssignment( methodRefX );
methodRefX.setAssignment( new SimpleAssignment( sourceReference ) );
methodRefX.setAssignment( new Simple( sourceReference ) );
break;
}
else {
@ -435,7 +435,7 @@ public class MappingResolver {
Type targetType ) {
MapperReference mapperReference = findMapperReference( mapperReferences, method );
return AssignmentFactory.createAssignment(
return AssignmentFactory.createMethodReference(
method,
mapperReference,
SourceMethod.containsTargetTypeParameter( method.getParameters() ) ? targetType : null

View File

@ -51,4 +51,14 @@ public class Collections {
return set;
}
public static <T> Set<T> asSet(Collection<T> collection, Collection<T>... elements) {
Set<T> set = new HashSet<T>( collection );
for ( Collection<T> element : elements ) {
set.addAll( element );
}
return set;
}
}

View File

@ -18,4 +18,11 @@
limitations under the License.
-->
${ext.target}( new <#if ext.targetType.implementationType??><@includeModel object=ext.targetType.implementationType/><#else><@includeModel object=ext.targetType/></#if>( ${sourceReference} ) );
<@compress single_line=true>
new <#if ext.targetType.implementationType??>
<@includeModel object=ext.targetType.implementationType/>
<#else>
<@includeModel object=ext.targetType/>
</#if>
( <@includeModel object=assignment target=ext.target targetType=ext.targetType raw=ext.raw/> )
</@compress>