mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#163 Adding support for decorators
This commit is contained in:
parent
427cc16390
commit
e0da882540
56
core/src/main/java/org/mapstruct/DecoratedWith.java
Normal file
56
core/src/main/java/org/mapstruct/DecoratedWith.java
Normal 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;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Specifies a decorator to be applied to a generated mapper, which e.g. can be used to amend mappings performed by
|
||||
* generated mapping methods.
|
||||
* <p>
|
||||
* A typical decorator implementation will be an abstract class and only implement/override a subset of the methods of
|
||||
* the mapper type which it decorates. All methods not implemented or overridden by the decorator will be implemented by
|
||||
* the code generator.
|
||||
* <p>
|
||||
* If a constructor with a single parameter accepting the type of the decorated mapper is present, a delegate with
|
||||
* generated implementations of all the mapper methods will be passed to this constructor. A typical implementation will
|
||||
* store the passed delegate in a field of the decorator and make use of it in the decorator methods.
|
||||
* <p>
|
||||
* <b>NOTE:</b> The decorator feature is considered experimental and it may change in future releases. Currently
|
||||
* decorators are only supported for the default component model, not for the CDI and Spring models.
|
||||
*
|
||||
* @author Gunnar Morling
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface DecoratedWith {
|
||||
|
||||
/**
|
||||
* The decorator type. Must extend or implement the mapper type to which it is applied.
|
||||
* <p>
|
||||
* The decorator type must either have a default constructor or a constructor with a single parameter accepting the
|
||||
* type of the decorated mapper.
|
||||
*
|
||||
* @return the decorator type
|
||||
*/
|
||||
Class<?> value();
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
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;
|
||||
import org.mapstruct.ap.prism.DecoratedWithPrism;
|
||||
|
||||
/**
|
||||
* Represents a decorator applied to a generated mapper type.
|
||||
*
|
||||
* @author Gunnar Morling
|
||||
*/
|
||||
public class Decorator extends GeneratedType {
|
||||
|
||||
private static final String IMPLEMENTATION_SUFFIX = "Impl";
|
||||
|
||||
private Decorator(TypeFactory typeFactory, String packageName, String name, String superClassName,
|
||||
String interfaceName, List<MappingMethod> methods, List<? extends ModelElement> fields,
|
||||
boolean suppressGeneratorTimestamp, Accessibility accessibility) {
|
||||
super(
|
||||
typeFactory,
|
||||
packageName,
|
||||
name,
|
||||
superClassName,
|
||||
interfaceName,
|
||||
methods,
|
||||
fields,
|
||||
suppressGeneratorTimestamp,
|
||||
accessibility
|
||||
);
|
||||
}
|
||||
|
||||
public static Decorator getInstance(Elements elementUtils, TypeFactory typeFactory, TypeElement mapperElement,
|
||||
DecoratedWithPrism decoratorPrism, List<MappingMethod> methods,
|
||||
boolean hasDelegateConstructor,
|
||||
boolean suppressGeneratorTimestamp) {
|
||||
Type decoratorType = typeFactory.getType( decoratorPrism.value() );
|
||||
|
||||
return new Decorator(
|
||||
typeFactory,
|
||||
elementUtils.getPackageOf( mapperElement ).getQualifiedName().toString(),
|
||||
mapperElement.getSimpleName().toString() + IMPLEMENTATION_SUFFIX,
|
||||
decoratorType.getName(),
|
||||
mapperElement.getKind() == ElementKind.INTERFACE ? mapperElement.getSimpleName().toString() : null,
|
||||
methods,
|
||||
Arrays.asList(
|
||||
new Field( typeFactory.getType( mapperElement ), "delegate" ),
|
||||
new DecoratorConstructor(
|
||||
mapperElement.getSimpleName().toString() + IMPLEMENTATION_SUFFIX,
|
||||
mapperElement.getSimpleName().toString() + "Impl_",
|
||||
hasDelegateConstructor
|
||||
)
|
||||
),
|
||||
suppressGeneratorTimestamp,
|
||||
Accessibility.fromModifiers( mapperElement.getModifiers() )
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTemplateName() {
|
||||
return GeneratedType.class.getName() + ".ftl";
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.mapstruct.ap.model.common.ModelElement;
|
||||
import org.mapstruct.ap.model.common.Type;
|
||||
|
||||
/**
|
||||
* Represents the constructor of a decorator.
|
||||
*
|
||||
* @author Gunnar Morling
|
||||
*/
|
||||
public class DecoratorConstructor extends ModelElement {
|
||||
|
||||
private final String name;
|
||||
private final String delegateName;
|
||||
private final boolean invokeSuperConstructor;
|
||||
|
||||
public DecoratorConstructor(String name, String delegateName, boolean invokeSuperConstructor) {
|
||||
this.name = name;
|
||||
this.delegateName = delegateName;
|
||||
this.invokeSuperConstructor = invokeSuperConstructor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Type> getImportTypes() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getDelegateName() {
|
||||
return delegateName;
|
||||
}
|
||||
|
||||
public boolean isInvokeSuperConstructor() {
|
||||
return invokeSuperConstructor;
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
import org.mapstruct.ap.model.source.Method;
|
||||
|
||||
/**
|
||||
* A method of a decorator which delegates to the corresponding method of the generated mapper implementation.
|
||||
*
|
||||
* @author Gunnar Morling
|
||||
*/
|
||||
public class DelegatingMethod extends MappingMethod {
|
||||
|
||||
public DelegatingMethod(Method method) {
|
||||
super( method );
|
||||
}
|
||||
}
|
@ -35,13 +35,15 @@ import org.mapstruct.ap.model.common.TypeFactory;
|
||||
public class Mapper extends GeneratedType {
|
||||
|
||||
private static final String IMPLEMENTATION_SUFFIX = "Impl";
|
||||
private static final String DECORATED_IMPLEMENTATION_SUFFIX = "Impl_";
|
||||
|
||||
private final List<MapperReference> referencedMappers;
|
||||
private final Decorator decorator;
|
||||
|
||||
private Mapper(TypeFactory typeFactory, String packageName, String name, String superClassName,
|
||||
String interfaceName,
|
||||
List<MappingMethod> methods, boolean suppressGeneratorTimestamp, Accessibility accessibility,
|
||||
List<MapperReference> referencedMappers) {
|
||||
List<MapperReference> referencedMappers, Decorator decorator) {
|
||||
|
||||
super(
|
||||
typeFactory,
|
||||
@ -56,6 +58,7 @@ public class Mapper extends GeneratedType {
|
||||
);
|
||||
|
||||
this.referencedMappers = referencedMappers;
|
||||
this.decorator = decorator;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
@ -67,6 +70,7 @@ public class Mapper extends GeneratedType {
|
||||
|
||||
private Elements elementUtils;
|
||||
private boolean suppressGeneratorTimestamp;
|
||||
private Decorator decorator;
|
||||
|
||||
public Builder element(TypeElement element) {
|
||||
this.element = element;
|
||||
@ -98,8 +102,14 @@ public class Mapper extends GeneratedType {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder decorator(Decorator decorator) {
|
||||
this.decorator = decorator;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Mapper build() {
|
||||
String implementationName = element.getSimpleName() + IMPLEMENTATION_SUFFIX;
|
||||
String implementationName = element.getSimpleName()
|
||||
+ ( decorator == null ? IMPLEMENTATION_SUFFIX : DECORATED_IMPLEMENTATION_SUFFIX );
|
||||
|
||||
return new Mapper(
|
||||
typeFactory,
|
||||
@ -110,7 +120,8 @@ public class Mapper extends GeneratedType {
|
||||
mappingMethods,
|
||||
suppressGeneratorTimestamp,
|
||||
Accessibility.fromModifiers( element.getModifiers() ),
|
||||
mapperReferences
|
||||
mapperReferences,
|
||||
decorator
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -119,6 +130,10 @@ public class Mapper extends GeneratedType {
|
||||
return referencedMappers;
|
||||
}
|
||||
|
||||
public Decorator getDecorator() {
|
||||
return decorator;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTemplateName() {
|
||||
return GeneratedType.class.getName() + ".ftl";
|
||||
|
@ -19,16 +19,17 @@
|
||||
package org.mapstruct.ap.prism;
|
||||
|
||||
import javax.xml.bind.annotation.XmlElementDecl;
|
||||
|
||||
import net.java.dev.hickory.prism.GeneratePrism;
|
||||
import net.java.dev.hickory.prism.GeneratePrisms;
|
||||
|
||||
import org.mapstruct.DecoratedWith;
|
||||
import org.mapstruct.IterableMapping;
|
||||
import org.mapstruct.MapMapping;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.MappingTarget;
|
||||
import org.mapstruct.TargetType;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.TargetType;
|
||||
|
||||
/**
|
||||
* Triggers the generation of prism types using <a href="https://java.net/projects/hickory">Hickory</a>.
|
||||
@ -43,6 +44,7 @@ import org.mapstruct.Mappings;
|
||||
@GeneratePrism(value = MapMapping.class, publicAccess = true),
|
||||
@GeneratePrism(value = TargetType.class, publicAccess = true),
|
||||
@GeneratePrism(value = MappingTarget.class, publicAccess = true),
|
||||
@GeneratePrism(value = DecoratedWith.class, publicAccess = true),
|
||||
|
||||
// external types
|
||||
@GeneratePrism(value = XmlElementDecl.class, publicAccess = true)
|
||||
|
@ -32,6 +32,7 @@ import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.type.TypeKind;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.lang.model.util.ElementFilter;
|
||||
import javax.lang.model.util.Elements;
|
||||
import javax.lang.model.util.Types;
|
||||
import javax.tools.Diagnostic.Kind;
|
||||
@ -39,7 +40,9 @@ import javax.tools.Diagnostic.Kind;
|
||||
import org.mapstruct.ap.conversion.ConversionProvider;
|
||||
import org.mapstruct.ap.conversion.Conversions;
|
||||
import org.mapstruct.ap.model.BeanMappingMethod;
|
||||
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.IterableMappingMethod;
|
||||
import org.mapstruct.ap.model.MapMappingMethod;
|
||||
@ -64,6 +67,7 @@ import org.mapstruct.ap.model.source.builtin.BuiltInMethod;
|
||||
import org.mapstruct.ap.model.source.selector.MethodSelectors;
|
||||
import org.mapstruct.ap.option.Options;
|
||||
import org.mapstruct.ap.option.ReportingPolicy;
|
||||
import org.mapstruct.ap.prism.DecoratedWithPrism;
|
||||
import org.mapstruct.ap.prism.MapperPrism;
|
||||
import org.mapstruct.ap.util.Executables;
|
||||
import org.mapstruct.ap.util.Filters;
|
||||
@ -127,6 +131,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
||||
.mappingMethods( mappingMethods )
|
||||
.mapperReferences( mapperReferences )
|
||||
.suppressGeneratorTimestamp( options.isSuppressGeneratorTimestamp() )
|
||||
.decorator( getDecorator( element, methods ) )
|
||||
.typeFactory( typeFactory )
|
||||
.elementUtils( elementUtils )
|
||||
.build();
|
||||
@ -159,6 +164,70 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
||||
}
|
||||
}
|
||||
|
||||
private Decorator getDecorator(TypeElement element, List<SourceMethod> methods) {
|
||||
DecoratedWithPrism decoratorPrism = DecoratedWithPrism.getInstanceOn( element );
|
||||
|
||||
if ( decoratorPrism == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
TypeElement decoratorElement = (TypeElement) typeUtils.asElement( decoratorPrism.value() );
|
||||
|
||||
List<MappingMethod> mappingMethods = new ArrayList<MappingMethod>( methods.size() );
|
||||
|
||||
for ( SourceMethod mappingMethod : methods ) {
|
||||
boolean implementationRequired = true;
|
||||
for ( ExecutableElement method : ElementFilter.methodsIn( decoratorElement.getEnclosedElements() ) ) {
|
||||
if ( elementUtils.overrides( method, mappingMethod.getExecutable(), decoratorElement ) ) {
|
||||
implementationRequired = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( implementationRequired ) {
|
||||
mappingMethods.add( new DelegatingMethod( mappingMethod ) );
|
||||
}
|
||||
}
|
||||
|
||||
boolean hasDelegateConstructor = false;
|
||||
boolean hasDefaultConstructor = false;
|
||||
for ( ExecutableElement constructor : ElementFilter.constructorsIn( decoratorElement.getEnclosedElements() ) ) {
|
||||
if ( constructor.getParameters().isEmpty() ) {
|
||||
hasDefaultConstructor = true;
|
||||
}
|
||||
else if ( constructor.getParameters().size() == 1 ) {
|
||||
if ( typeUtils.isAssignable(
|
||||
element.asType(),
|
||||
constructor.getParameters().iterator().next().asType()
|
||||
) ) {
|
||||
hasDelegateConstructor = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !hasDelegateConstructor && !hasDefaultConstructor ) {
|
||||
messager.printMessage(
|
||||
Kind.ERROR,
|
||||
String.format(
|
||||
"Specified decorator type has no default constructor nor a constructor with a single " +
|
||||
"parameter accepting the decorated mapper type."
|
||||
),
|
||||
element,
|
||||
decoratorPrism.mirror
|
||||
);
|
||||
}
|
||||
|
||||
return Decorator.getInstance(
|
||||
elementUtils,
|
||||
typeFactory,
|
||||
element,
|
||||
decoratorPrism,
|
||||
mappingMethods,
|
||||
hasDelegateConstructor,
|
||||
options.isSuppressGeneratorTimestamp()
|
||||
);
|
||||
}
|
||||
|
||||
private List<MapperReference> getReferencedMappers(TypeElement element) {
|
||||
List<MapperReference> mapperReferences = new LinkedList<MapperReference>();
|
||||
List<String> variableNames = new LinkedList<String>();
|
||||
|
@ -48,6 +48,10 @@ public class MapperRenderingProcessor implements ModelElementProcessor<Mapper, V
|
||||
ModelWriter modelWriter = new ModelWriter();
|
||||
|
||||
createSourceFile( model, modelWriter, filer );
|
||||
|
||||
if ( model.getDecorator() != null ) {
|
||||
createSourceFile( model.getDecorator(), modelWriter, filer );
|
||||
}
|
||||
}
|
||||
|
||||
private void createSourceFile(GeneratedType model, ModelWriter modelWriter, Filer filer) {
|
||||
|
@ -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.
|
||||
|
||||
-->
|
||||
public ${name}() {
|
||||
<#if invokeSuperConstructor>
|
||||
super( new ${delegateName}() );
|
||||
</#if>
|
||||
this.delegate = new ${delegateName}();
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
<#--
|
||||
|
||||
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.
|
||||
|
||||
-->
|
||||
@Override
|
||||
public <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, </#if></#list>) {
|
||||
return delegate.${name}( <#list parameters as param>${param.name}<#if param_has_next>, </#if></#list> );
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* 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.decorator;
|
||||
|
||||
public class Address {
|
||||
|
||||
private String addressLine;
|
||||
|
||||
public Address(String addressLine) {
|
||||
this.addressLine = addressLine;
|
||||
}
|
||||
|
||||
public String getAddressLine() {
|
||||
return addressLine;
|
||||
}
|
||||
|
||||
public void setAddressLine(String addressLine) {
|
||||
this.addressLine = addressLine;
|
||||
}
|
||||
}
|
@ -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.decorator;
|
||||
|
||||
public class AddressDto {
|
||||
|
||||
private String addressLine;
|
||||
|
||||
public String getAddressLine() {
|
||||
return addressLine;
|
||||
}
|
||||
|
||||
public void setAddressLine(String addressLine) {
|
||||
this.addressLine = addressLine;
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* 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.decorator;
|
||||
|
||||
import org.mapstruct.DecoratedWith;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.ReportingPolicy;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE)
|
||||
@DecoratedWith(AnotherPersonMapperDecorator.class)
|
||||
public interface AnotherPersonMapper {
|
||||
|
||||
AnotherPersonMapper INSTANCE = Mappers.getMapper( AnotherPersonMapper.class );
|
||||
|
||||
PersonDto personToPersonDto(Person person);
|
||||
|
||||
AddressDto addressToAddressDto(Address address);
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* 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.decorator;
|
||||
|
||||
public abstract class AnotherPersonMapperDecorator implements AnotherPersonMapper {
|
||||
|
||||
@Override
|
||||
public PersonDto personToPersonDto(Person person) {
|
||||
AddressDto addressDto = new AddressDto();
|
||||
addressDto.setAddressLine( person.getAddress().getAddressLine() );
|
||||
|
||||
PersonDto dto = new PersonDto();
|
||||
dto.setDateOfBirth( person.getDateOfBirth() );
|
||||
dto.setName( person.getFirstName() + " " + person.getLastName() );
|
||||
dto.setAddress( addressDto );
|
||||
|
||||
return dto;
|
||||
}
|
||||
}
|
@ -0,0 +1,123 @@
|
||||
/**
|
||||
* 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.decorator;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
import org.mapstruct.ap.testutil.IssueKey;
|
||||
import org.mapstruct.ap.testutil.MapperTestBase;
|
||||
import org.mapstruct.ap.testutil.WithClasses;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.fest.assertions.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Test for the application of decorators.
|
||||
*
|
||||
* @author Gunnar Morling
|
||||
*/
|
||||
@WithClasses({
|
||||
Person.class,
|
||||
PersonDto.class,
|
||||
Address.class,
|
||||
AddressDto.class
|
||||
})
|
||||
@IssueKey("163")
|
||||
public class DecoratorTest extends MapperTestBase {
|
||||
|
||||
@Test
|
||||
@WithClasses({
|
||||
PersonMapper.class,
|
||||
PersonMapperDecorator.class
|
||||
})
|
||||
public void shouldInvokeDecoratorMethods() {
|
||||
//given
|
||||
Calendar birthday = Calendar.getInstance();
|
||||
birthday.set( 1928, 4, 23 );
|
||||
Person person = new Person( "Gary", "Crant", birthday.getTime(), new Address( "42 Ocean View Drive" ) );
|
||||
|
||||
//when
|
||||
PersonDto personDto = PersonMapper.INSTANCE.personToPersonDto( person );
|
||||
|
||||
//then
|
||||
assertThat( personDto ).isNotNull();
|
||||
assertThat( personDto.getName() ).isEqualTo( "Gary Crant" );
|
||||
assertThat( personDto.getAddress() ).isNotNull();
|
||||
assertThat( personDto.getAddress().getAddressLine() ).isEqualTo( "42 Ocean View Drive" );
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithClasses({
|
||||
PersonMapper.class,
|
||||
PersonMapperDecorator.class
|
||||
})
|
||||
public void shouldDelegateNonDecoratedMethodsToDefaultImplementation() {
|
||||
//given
|
||||
Address address = new Address( "42 Ocean View Drive" );
|
||||
|
||||
//when
|
||||
AddressDto addressDto = PersonMapper.INSTANCE.addressToAddressDto( address );
|
||||
|
||||
//then
|
||||
assertThat( addressDto ).isNotNull();
|
||||
assertThat( addressDto.getAddressLine() ).isEqualTo( "42 Ocean View Drive" );
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithClasses({
|
||||
AnotherPersonMapper.class,
|
||||
AnotherPersonMapperDecorator.class
|
||||
})
|
||||
public void shouldApplyDecoratorWithDefaultConstructor() {
|
||||
//given
|
||||
Calendar birthday = Calendar.getInstance();
|
||||
birthday.set( 1928, 4, 23 );
|
||||
Person person = new Person( "Gary", "Crant", birthday.getTime(), new Address( "42 Ocean View Drive" ) );
|
||||
|
||||
//when
|
||||
PersonDto personDto = AnotherPersonMapper.INSTANCE.personToPersonDto( person );
|
||||
|
||||
//then
|
||||
assertThat( personDto ).isNotNull();
|
||||
assertThat( personDto.getName() ).isEqualTo( "Gary Crant" );
|
||||
assertThat( personDto.getAddress() ).isNotNull();
|
||||
assertThat( personDto.getAddress().getAddressLine() ).isEqualTo( "42 Ocean View Drive" );
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithClasses({
|
||||
YetAnotherPersonMapper.class,
|
||||
YetAnotherPersonMapperDecorator.class
|
||||
})
|
||||
public void shouldApplyDelegateToClassBasedMapper() {
|
||||
//given
|
||||
Calendar birthday = Calendar.getInstance();
|
||||
birthday.set( 1928, 4, 23 );
|
||||
Person person = new Person( "Gary", "Crant", birthday.getTime(), new Address( "42 Ocean View Drive" ) );
|
||||
|
||||
//when
|
||||
PersonDto personDto = YetAnotherPersonMapper.INSTANCE.personToPersonDto( person );
|
||||
|
||||
//then
|
||||
assertThat( personDto ).isNotNull();
|
||||
assertThat( personDto.getName() ).isEqualTo( "Gary Crant" );
|
||||
assertThat( personDto.getAddress() ).isNotNull();
|
||||
assertThat( personDto.getAddress().getAddressLine() ).isEqualTo( "42 Ocean View Drive" );
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/**
|
||||
* 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.decorator;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class Person {
|
||||
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private Date dateOfBirth;
|
||||
private Address address;
|
||||
|
||||
public Person(String firstName, String lastName, Date dateOfBirth, Address address) {
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
this.dateOfBirth = dateOfBirth;
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public Date getDateOfBirth() {
|
||||
return dateOfBirth;
|
||||
}
|
||||
|
||||
public void setDateOfBirth(Date dateOfBirth) {
|
||||
this.dateOfBirth = dateOfBirth;
|
||||
}
|
||||
|
||||
public Address getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(Address address) {
|
||||
this.address = address;
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/**
|
||||
* 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.decorator;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class PersonDto {
|
||||
|
||||
private String name;
|
||||
private Date dateOfBirth;
|
||||
private AddressDto address;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Date getDateOfBirth() {
|
||||
return dateOfBirth;
|
||||
}
|
||||
|
||||
public void setDateOfBirth(Date dateOfBirth) {
|
||||
this.dateOfBirth = dateOfBirth;
|
||||
}
|
||||
|
||||
public AddressDto getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(AddressDto address) {
|
||||
this.address = address;
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* 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.decorator;
|
||||
|
||||
import org.mapstruct.DecoratedWith;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.ReportingPolicy;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE)
|
||||
@DecoratedWith(PersonMapperDecorator.class)
|
||||
public interface PersonMapper {
|
||||
|
||||
PersonMapper INSTANCE = Mappers.getMapper( PersonMapper.class );
|
||||
|
||||
PersonDto personToPersonDto(Person person);
|
||||
|
||||
AddressDto addressToAddressDto(Address address);
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* 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.decorator;
|
||||
|
||||
public abstract class PersonMapperDecorator implements PersonMapper {
|
||||
|
||||
private final PersonMapper delegate;
|
||||
|
||||
public PersonMapperDecorator(PersonMapper delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PersonDto personToPersonDto(Person person) {
|
||||
PersonDto dto = delegate.personToPersonDto( person );
|
||||
dto.setName( person.getFirstName() + " " + person.getLastName() );
|
||||
|
||||
return dto;
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* 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.decorator;
|
||||
|
||||
import org.mapstruct.DecoratedWith;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.ReportingPolicy;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE)
|
||||
@DecoratedWith(YetAnotherPersonMapperDecorator.class)
|
||||
public abstract class YetAnotherPersonMapper {
|
||||
|
||||
public static final YetAnotherPersonMapper INSTANCE = Mappers.getMapper( YetAnotherPersonMapper.class );
|
||||
|
||||
public abstract PersonDto personToPersonDto(Person person);
|
||||
|
||||
public abstract AddressDto addressToAddressDto(Address address);
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* 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.decorator;
|
||||
|
||||
public abstract class YetAnotherPersonMapperDecorator extends YetAnotherPersonMapper {
|
||||
|
||||
@Override
|
||||
public PersonDto personToPersonDto(Person person) {
|
||||
AddressDto addressDto = new AddressDto();
|
||||
addressDto.setAddressLine( person.getAddress().getAddressLine() );
|
||||
|
||||
PersonDto dto = new PersonDto();
|
||||
dto.setDateOfBirth( person.getDateOfBirth() );
|
||||
dto.setName( person.getFirstName() + " " + person.getLastName() );
|
||||
dto.setAddress( addressDto );
|
||||
|
||||
return dto;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user