mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#592 Fix Decorator-support for component model 'spring' and 'jsr330', extend decorator integration-tests, add examples to @DecoratedWith javadoc
This commit is contained in:
parent
4eaacbcfe6
commit
590363cf2f
@ -29,14 +29,131 @@ import java.lang.annotation.Target;
|
|||||||
* <p>
|
* <p>
|
||||||
* A typical decorator implementation will be an abstract class and only implement/override a subset of the methods of
|
* 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 mapper type which it decorates. All methods not implemented or overridden by the decorator will be implemented by
|
||||||
* the code generator.
|
* the code generator by delegating to the generated mapper implementation.
|
||||||
|
* <p>
|
||||||
|
* <b>NOTE:</b> The usage of decorated mappers differs depending on the selected component model.
|
||||||
|
* <p>
|
||||||
|
* <b>NOTE:</b> This annotation is not supported for the component model {@code cdi}. Use CDI's own
|
||||||
|
* <a href="https://docs.jboss.org/cdi/spec/1.0/html/decorators.html">{@code @Decorator}</a> feature instead.
|
||||||
|
* <p>
|
||||||
|
* <b>NOTE:</b> The decorator feature when used with component model {@code jsr330} is considered <em>experimental</em>
|
||||||
|
* and it may change in future releases.
|
||||||
|
* <p>
|
||||||
|
* <h2>Examples</h2>
|
||||||
|
* <p>
|
||||||
|
* For the examples below, consider the following mapper declaration:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* @Mapper(componentModel = "...")
|
||||||
|
* @DecoratedWith(PersonMapperDecorator.class)
|
||||||
|
* public interface PersonMapper {
|
||||||
|
*
|
||||||
|
* @Mapping(target = "name", ignore = true)
|
||||||
|
* PersonDto personToPersonDto(Person person);
|
||||||
|
*
|
||||||
|
* AddressDto addressToAddressDto(Address address); // not touched by the decorator
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* <h3>1. Component model 'default'</h3>
|
||||||
|
* <h4>Referencing the original mapper in the decorator</h4>
|
||||||
* <p>
|
* <p>
|
||||||
* If a constructor with a single parameter accepting the type of the decorated mapper is present, a delegate with
|
* 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
|
* 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.
|
* store the passed delegate in a field of the decorator and make use of it in the decorator methods:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* public abstract class PersonMapperDecorator implements PersonMapper {
|
||||||
|
*
|
||||||
|
* private 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;
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* <h4>Using the decorated mapper</h4>
|
||||||
|
* <p>
|
||||||
|
* Nothing special needs to be done. When using {@code Mappers.getMapper( PersonMapper.class )}, the <em>decorator</em>
|
||||||
|
* is returned, with the injected original mapper.
|
||||||
|
* <h3>2. Component model 'spring'</h3>
|
||||||
|
* <h4>Referencing the original mapper in the decorator</h4>
|
||||||
|
* <p>
|
||||||
|
* The generated implementation of the original mapper is annotated with the Spring's {@code @Qualifier("delegate")}. To
|
||||||
|
* autowire that bean in your decorator, add that qualifier annotation as well:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* public abstract class PersonMapperDecorator implements PersonMapper {
|
||||||
|
*
|
||||||
|
* @Autowired
|
||||||
|
* @Qualifier("delegate")
|
||||||
|
* private PersonMapper delegate;
|
||||||
|
*
|
||||||
|
* @Override
|
||||||
|
* public PersonDto personToPersonDto(Person person) {
|
||||||
|
* PersonDto dto = delegate.personToPersonDto( person );
|
||||||
|
* dto.setName( person.getFirstName() + " " + person.getLastName() );
|
||||||
|
*
|
||||||
|
* return dto;
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* <h4>Using the decorated mapper in the decorator</h4>
|
||||||
|
* <p>
|
||||||
|
* The generated class that extends the decorator is annotated with Spring's {@code @Primary} annotation. To autowire
|
||||||
|
* the decorated mapper in the application, nothing special needs to be done:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* @Autowired
|
||||||
|
* private PersonMapper personMapper; // injects the decorator, with the injected original mapper
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* <h3>3. Component model 'jsr330'</h3>
|
||||||
|
* <h4>Referencing the original mapper</h4>
|
||||||
|
* <p>
|
||||||
|
* JSR 330 doesn't specify qualifiers and only allows to specifically name the beans. Hence, the generated
|
||||||
|
* implementation of the original mapper is annotated with the {@code @Named("fully-qualified-name-of-generated-impl")}.
|
||||||
|
* To inject that bean in your decorator, add the same annotation to the delegate field:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* public abstract class PersonMapperDecorator implements PersonMapper {
|
||||||
|
*
|
||||||
|
* @Inject
|
||||||
|
* @Named("org.examples.PersonMapperImpl_")
|
||||||
|
* private PersonMapper delegate;
|
||||||
|
*
|
||||||
|
* @Override
|
||||||
|
* public PersonDto personToPersonDto(Person person) {
|
||||||
|
* PersonDto dto = delegate.personToPersonDto( person );
|
||||||
|
* dto.setName( person.getFirstName() + " " + person.getLastName() );
|
||||||
|
*
|
||||||
|
* return dto;
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* <h4>Using the decorated mapper in the decorator</h4>
|
||||||
|
* <p>
|
||||||
|
* Unlike with the other component models, the usage site must be aware if a mapper is decorated or not, as for
|
||||||
|
* decorated mappers, the parameterless {@code @Named} annotation must be added to select the <em>decorator</em> to be
|
||||||
|
* injected:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* @Inject
|
||||||
|
* @Named
|
||||||
|
* private PersonMapper personMapper; // injects the decorator, with the injected original mapper
|
||||||
|
* </pre>
|
||||||
* <p>
|
* <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
|
* @author Gunnar Morling
|
||||||
*/
|
*/
|
||||||
@ -45,10 +162,10 @@ import java.lang.annotation.Target;
|
|||||||
public @interface DecoratedWith {
|
public @interface DecoratedWith {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The decorator type. Must extend or implement the mapper type to which it is applied.
|
* The decorator type. Must be an abstract class that extends or implements the mapper type to which it is applied.
|
||||||
* <p>
|
* <p>
|
||||||
* The decorator type must either have a default constructor or a constructor with a single parameter accepting the
|
* For component-model {@code default}, the decorator type must either have a default constructor or a constructor
|
||||||
* type of the decorated mapper.
|
* with a single parameter accepting the type of the decorated mapper.
|
||||||
*
|
*
|
||||||
* @return the decorator type
|
* @return the decorator type
|
||||||
*/
|
*/
|
||||||
|
@ -26,4 +26,6 @@ import org.mapstruct.itest.cdi.other.DateMapper;
|
|||||||
public interface DecoratedSourceTargetMapper {
|
public interface DecoratedSourceTargetMapper {
|
||||||
|
|
||||||
Target sourceToTarget(Source source);
|
Target sourceToTarget(Source source);
|
||||||
|
|
||||||
|
Target undecoratedSourceToTarget(Source source);
|
||||||
}
|
}
|
||||||
|
@ -23,15 +23,12 @@ import javax.decorator.Delegate;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@Decorator
|
@Decorator
|
||||||
public class SourceTargetMapperDecorator implements DecoratedSourceTargetMapper {
|
public abstract class SourceTargetMapperDecorator implements DecoratedSourceTargetMapper {
|
||||||
|
|
||||||
@Delegate
|
@Delegate
|
||||||
@Inject
|
@Inject
|
||||||
private DecoratedSourceTargetMapper delegate;
|
private DecoratedSourceTargetMapper delegate;
|
||||||
|
|
||||||
public SourceTargetMapperDecorator() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Target sourceToTarget(Source source) {
|
public Target sourceToTarget(Source source) {
|
||||||
Target t = delegate.sourceToTarget( source );
|
Target t = delegate.sourceToTarget( source );
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||||
|
* and/or other contributors as indicated by the @authors tag. See the
|
||||||
|
* copyright.txt file in the distribution for a full listing of all
|
||||||
|
* contributors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.mapstruct.itest.jsr330;
|
||||||
|
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.DecoratedWith;
|
||||||
|
import org.mapstruct.itest.jsr330.other.DateMapper;
|
||||||
|
|
||||||
|
@Mapper(componentModel = "jsr330", uses = DateMapper.class)
|
||||||
|
@DecoratedWith(SourceTargetMapperDecorator.class)
|
||||||
|
public interface DecoratedSourceTargetMapper {
|
||||||
|
|
||||||
|
Target sourceToTarget(Source source);
|
||||||
|
|
||||||
|
Target undecoratedSourceToTarget(Source source);
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||||
|
* and/or other contributors as indicated by the @authors tag. See the
|
||||||
|
* copyright.txt file in the distribution for a full listing of all
|
||||||
|
* contributors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.mapstruct.itest.jsr330;
|
||||||
|
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.DecoratedWith;
|
||||||
|
import org.mapstruct.itest.jsr330.other.DateMapper;
|
||||||
|
|
||||||
|
@Mapper(componentModel = "jsr330", uses = DateMapper.class)
|
||||||
|
@DecoratedWith(SecondSourceTargetMapperDecorator.class)
|
||||||
|
public interface SecondDecoratedSourceTargetMapper {
|
||||||
|
|
||||||
|
Target sourceToTarget(Source source);
|
||||||
|
|
||||||
|
Target undecoratedSourceToTarget(Source source);
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||||
|
* and/or other contributors as indicated by the @authors tag. See the
|
||||||
|
* copyright.txt file in the distribution for a full listing of all
|
||||||
|
* contributors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.mapstruct.itest.jsr330;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
|
public abstract class SecondSourceTargetMapperDecorator implements SecondDecoratedSourceTargetMapper {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Named("org.mapstruct.itest.jsr330.SecondDecoratedSourceTargetMapperImpl_")
|
||||||
|
private SecondDecoratedSourceTargetMapper delegate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Target sourceToTarget(Source source) {
|
||||||
|
Target t = delegate.sourceToTarget( source );
|
||||||
|
t.setFoo( 43L );
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||||
|
* and/or other contributors as indicated by the @authors tag. See the
|
||||||
|
* copyright.txt file in the distribution for a full listing of all
|
||||||
|
* contributors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.mapstruct.itest.jsr330;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
|
public abstract class SourceTargetMapperDecorator implements DecoratedSourceTargetMapper {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Named("org.mapstruct.itest.jsr330.DecoratedSourceTargetMapperImpl_")
|
||||||
|
private DecoratedSourceTargetMapper delegate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Target sourceToTarget(Source source) {
|
||||||
|
Target t = delegate.sourceToTarget( source );
|
||||||
|
t.setFoo( 43L );
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
@ -18,9 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.itest.jsr330;
|
package org.mapstruct.itest.jsr330;
|
||||||
|
|
||||||
import static org.fest.assertions.Assertions.assertThat;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@ -30,13 +29,15 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
|
||||||
|
import static org.fest.assertions.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test for generation of JSR-330-based Mapper implementations
|
* Test for generation of JSR-330-based Mapper implementations
|
||||||
*
|
*
|
||||||
* @author Andreas Gudian
|
* @author Andreas Gudian
|
||||||
*/
|
*/
|
||||||
@ContextConfiguration(classes = SpringTestConfig.class )
|
@ContextConfiguration(classes = SpringTestConfig.class)
|
||||||
@RunWith( SpringJUnit4ClassRunner.class )
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
public class Jsr330BasedMapperTest {
|
public class Jsr330BasedMapperTest {
|
||||||
@Configuration
|
@Configuration
|
||||||
@ComponentScan(basePackageClasses = Jsr330BasedMapperTest.class)
|
@ComponentScan(basePackageClasses = Jsr330BasedMapperTest.class)
|
||||||
@ -46,9 +47,16 @@ public class Jsr330BasedMapperTest {
|
|||||||
@Inject
|
@Inject
|
||||||
private SourceTargetMapper mapper;
|
private SourceTargetMapper mapper;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Named
|
||||||
|
private DecoratedSourceTargetMapper decoratedMapper;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Named
|
||||||
|
private SecondDecoratedSourceTargetMapper secondDecoratedMapper;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldCreateSpringBasedMapper() {
|
public void shouldInjectJsr330BasedMapper() {
|
||||||
Source source = new Source();
|
Source source = new Source();
|
||||||
|
|
||||||
Target target = mapper.sourceToTarget( source );
|
Target target = mapper.sourceToTarget( source );
|
||||||
@ -57,4 +65,38 @@ public class Jsr330BasedMapperTest {
|
|||||||
assertThat( target.getFoo() ).isEqualTo( Long.valueOf( 42 ) );
|
assertThat( target.getFoo() ).isEqualTo( Long.valueOf( 42 ) );
|
||||||
assertThat( target.getDate() ).isEqualTo( "1980" );
|
assertThat( target.getDate() ).isEqualTo( "1980" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldInjectDecorator() {
|
||||||
|
Source source = new Source();
|
||||||
|
|
||||||
|
Target target = decoratedMapper.sourceToTarget( source );
|
||||||
|
|
||||||
|
assertThat( target ).isNotNull();
|
||||||
|
assertThat( target.getFoo() ).isEqualTo( Long.valueOf( 43 ) );
|
||||||
|
assertThat( target.getDate() ).isEqualTo( "1980" );
|
||||||
|
|
||||||
|
target = decoratedMapper.undecoratedSourceToTarget( source );
|
||||||
|
|
||||||
|
assertThat( target ).isNotNull();
|
||||||
|
assertThat( target.getFoo() ).isEqualTo( Long.valueOf( 42 ) );
|
||||||
|
assertThat( target.getDate() ).isEqualTo( "1980" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldInjectSecondDecorator() {
|
||||||
|
Source source = new Source();
|
||||||
|
|
||||||
|
Target target = secondDecoratedMapper.sourceToTarget( source );
|
||||||
|
|
||||||
|
assertThat( target ).isNotNull();
|
||||||
|
assertThat( target.getFoo() ).isEqualTo( Long.valueOf( 43 ) );
|
||||||
|
assertThat( target.getDate() ).isEqualTo( "1980" );
|
||||||
|
|
||||||
|
target = secondDecoratedMapper.undecoratedSourceToTarget( source );
|
||||||
|
|
||||||
|
assertThat( target ).isNotNull();
|
||||||
|
assertThat( target.getFoo() ).isEqualTo( Long.valueOf( 42 ) );
|
||||||
|
assertThat( target.getDate() ).isEqualTo( "1980" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,4 +27,6 @@ import org.mapstruct.itest.spring.other.DateMapper;
|
|||||||
public interface DecoratedSourceTargetMapper {
|
public interface DecoratedSourceTargetMapper {
|
||||||
|
|
||||||
Target sourceToTarget(Source source);
|
Target sourceToTarget(Source source);
|
||||||
|
|
||||||
|
Target undecoratedSourceToTarget(Source source);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||||
|
* and/or other contributors as indicated by the @authors tag. See the
|
||||||
|
* copyright.txt file in the distribution for a full listing of all
|
||||||
|
* contributors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.mapstruct.itest.spring;
|
||||||
|
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.DecoratedWith;
|
||||||
|
import org.mapstruct.itest.spring.other.DateMapper;
|
||||||
|
|
||||||
|
@Mapper( componentModel = "spring", uses = DateMapper.class )
|
||||||
|
@DecoratedWith( SecondSourceTargetMapperDecorator.class )
|
||||||
|
public interface SecondDecoratedSourceTargetMapper {
|
||||||
|
|
||||||
|
Target sourceToTarget(Source source);
|
||||||
|
|
||||||
|
Target undecoratedSourceToTarget(Source source);
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||||
|
* and/or other contributors as indicated by the @authors tag. See the
|
||||||
|
* copyright.txt file in the distribution for a full listing of all
|
||||||
|
* contributors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.mapstruct.itest.spring;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
|
||||||
|
public abstract class SecondSourceTargetMapperDecorator implements SecondDecoratedSourceTargetMapper {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Qualifier( "delegate" )
|
||||||
|
private DecoratedSourceTargetMapper delegate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Target sourceToTarget(Source source) {
|
||||||
|
Target t = delegate.sourceToTarget( source );
|
||||||
|
t.setFoo( 43L );
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
@ -20,20 +20,13 @@ package org.mapstruct.itest.spring;
|
|||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.context.annotation.Primary;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
@Component
|
public abstract class SourceTargetMapperDecorator implements DecoratedSourceTargetMapper {
|
||||||
@Primary
|
|
||||||
public class SourceTargetMapperDecorator implements DecoratedSourceTargetMapper {
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@Qualifier( "delegate" )
|
@Qualifier( "delegate" )
|
||||||
private DecoratedSourceTargetMapper delegate;
|
private DecoratedSourceTargetMapper delegate;
|
||||||
|
|
||||||
public SourceTargetMapperDecorator() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Target sourceToTarget(Source source) {
|
public Target sourceToTarget(Source source) {
|
||||||
Target t = delegate.sourceToTarget( source );
|
Target t = delegate.sourceToTarget( source );
|
||||||
|
@ -18,25 +18,24 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.itest.spring;
|
package org.mapstruct.itest.spring;
|
||||||
|
|
||||||
import static org.fest.assertions.Assertions.assertThat;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mapstruct.itest.spring.SpringBasedMapperTest.SpringTestConfig;
|
import org.mapstruct.itest.spring.SpringBasedMapperTest.SpringTestConfig;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
|
||||||
|
import static org.fest.assertions.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test for generation of Spring-based Mapper implementations
|
* Test for generation of Spring-based Mapper implementations
|
||||||
*
|
*
|
||||||
* @author Andreas Gudian
|
* @author Andreas Gudian
|
||||||
*/
|
*/
|
||||||
@ContextConfiguration(classes = SpringTestConfig.class )
|
@ContextConfiguration(classes = SpringTestConfig.class)
|
||||||
@RunWith( SpringJUnit4ClassRunner.class )
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
public class SpringBasedMapperTest {
|
public class SpringBasedMapperTest {
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@ -50,8 +49,11 @@ public class SpringBasedMapperTest {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private DecoratedSourceTargetMapper decoratedMapper;
|
private DecoratedSourceTargetMapper decoratedMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SecondDecoratedSourceTargetMapper secondDecoratedMapper;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldCreateSpringBasedMapper() {
|
public void shouldInjectSpringBasedMapper() {
|
||||||
Source source = new Source();
|
Source source = new Source();
|
||||||
|
|
||||||
Target target = mapper.sourceToTarget( source );
|
Target target = mapper.sourceToTarget( source );
|
||||||
@ -69,5 +71,29 @@ public class SpringBasedMapperTest {
|
|||||||
|
|
||||||
assertThat( target ).isNotNull();
|
assertThat( target ).isNotNull();
|
||||||
assertThat( target.getFoo() ).isEqualTo( Long.valueOf( 43 ) );
|
assertThat( target.getFoo() ).isEqualTo( Long.valueOf( 43 ) );
|
||||||
|
assertThat( target.getDate() ).isEqualTo( "1980" );
|
||||||
|
|
||||||
|
target = decoratedMapper.undecoratedSourceToTarget( source );
|
||||||
|
|
||||||
|
assertThat( target ).isNotNull();
|
||||||
|
assertThat( target.getFoo() ).isEqualTo( Long.valueOf( 42 ) );
|
||||||
|
assertThat( target.getDate() ).isEqualTo( "1980" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldInjectSecondDecorator() {
|
||||||
|
Source source = new Source();
|
||||||
|
|
||||||
|
Target target = secondDecoratedMapper.sourceToTarget( source );
|
||||||
|
|
||||||
|
assertThat( target ).isNotNull();
|
||||||
|
assertThat( target.getFoo() ).isEqualTo( Long.valueOf( 43 ) );
|
||||||
|
assertThat( target.getDate() ).isEqualTo( "1980" );
|
||||||
|
|
||||||
|
target = secondDecoratedMapper.undecoratedSourceToTarget( source );
|
||||||
|
|
||||||
|
assertThat( target ).isNotNull();
|
||||||
|
assertThat( target.getFoo() ).isEqualTo( Long.valueOf( 42 ) );
|
||||||
|
assertThat( target.getDate() ).isEqualTo( "1980" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,6 +179,12 @@
|
|||||||
<version>${org.springframework.version}</version>
|
<version>${org.springframework.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-logging</groupId>
|
||||||
|
<artifactId>commons-logging</artifactId>
|
||||||
|
<version>1.1.3</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- Joda-Time -->
|
<!-- Joda-Time -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>joda-time</groupId>
|
<groupId>joda-time</groupId>
|
||||||
|
@ -85,6 +85,23 @@
|
|||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Spring -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-beans</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-context</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- There is no compile dependency to Joda-Time; It's only required for testing the Joda conversions -->
|
<!-- There is no compile dependency to Joda-Time; It's only required for testing the Joda conversions -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>joda-time</groupId>
|
<groupId>joda-time</groupId>
|
||||||
|
@ -18,10 +18,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.internal.model;
|
package org.mapstruct.ap.internal.model;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.mapstruct.ap.internal.model.common.Type;
|
import org.mapstruct.ap.internal.model.common.Type;
|
||||||
import org.mapstruct.ap.internal.util.Collections;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mapper reference which is retrieved via Annotation-based dependency injection.
|
* Mapper reference which is retrieved via Annotation-based dependency injection.
|
||||||
@ -31,19 +32,26 @@ import org.mapstruct.ap.internal.util.Collections;
|
|||||||
*/
|
*/
|
||||||
public class AnnotationMapperReference extends MapperReference {
|
public class AnnotationMapperReference extends MapperReference {
|
||||||
|
|
||||||
private final Annotation annotation;
|
private final List<Annotation> annotations;
|
||||||
|
|
||||||
public AnnotationMapperReference(Type type, String variableName, Annotation annotation, boolean isUsed) {
|
public AnnotationMapperReference(Type type, String variableName, List<Annotation> annotations, boolean isUsed) {
|
||||||
super( type, variableName, isUsed );
|
super( type, variableName, isUsed );
|
||||||
this.annotation = annotation;
|
this.annotations = annotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Annotation getAnnotation() {
|
public List<Annotation> getAnnotations() {
|
||||||
return annotation;
|
return annotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Type> getImportTypes() {
|
public Set<Type> getImportTypes() {
|
||||||
return Collections.asSet( annotation.getImportTypes(), super.getType() );
|
Set<Type> types = new HashSet<Type>();
|
||||||
|
types.add( getType() );
|
||||||
|
|
||||||
|
for ( Annotation annotation : annotations ) {
|
||||||
|
types.addAll( annotation.getImportTypes() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return types;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,14 +50,14 @@ public abstract class GeneratedType extends ModelElement {
|
|||||||
|
|
||||||
private final List<Annotation> annotations;
|
private final List<Annotation> annotations;
|
||||||
private final List<MappingMethod> methods;
|
private final List<MappingMethod> methods;
|
||||||
private final List<? extends Field> fields;
|
|
||||||
private final SortedSet<Type> extraImportedTypes;
|
private final SortedSet<Type> extraImportedTypes;
|
||||||
|
|
||||||
private final boolean suppressGeneratorTimestamp;
|
private final boolean suppressGeneratorTimestamp;
|
||||||
private final boolean suppressGeneratorVersionComment;
|
private final boolean suppressGeneratorVersionComment;
|
||||||
private final VersionInformation versionInformation;
|
private final VersionInformation versionInformation;
|
||||||
private final Accessibility accessibility;
|
private final Accessibility accessibility;
|
||||||
private final Constructor constructor;
|
private List<? extends Field> fields;
|
||||||
|
private Constructor constructor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type representing the {@code @Generated} annotation
|
* Type representing the {@code @Generated} annotation
|
||||||
@ -128,10 +128,14 @@ public abstract class GeneratedType extends ModelElement {
|
|||||||
return methods;
|
return methods;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<? extends ModelElement> getFields() {
|
public List<? extends Field> getFields() {
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setFields(List<? extends Field> fields) {
|
||||||
|
this.fields = fields;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isSuppressGeneratorTimestamp() {
|
public boolean isSuppressGeneratorTimestamp() {
|
||||||
return suppressGeneratorTimestamp;
|
return suppressGeneratorTimestamp;
|
||||||
}
|
}
|
||||||
@ -182,6 +186,10 @@ public abstract class GeneratedType extends ModelElement {
|
|||||||
return constructor;
|
return constructor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void removeConstructor() {
|
||||||
|
constructor = null;
|
||||||
|
}
|
||||||
|
|
||||||
protected void addWithDependents(Collection<Type> collection, Type typeToAdd) {
|
protected void addWithDependents(Collection<Type> collection, Type typeToAdd) {
|
||||||
if ( typeToAdd == null ) {
|
if ( typeToAdd == null ) {
|
||||||
return;
|
return;
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.internal.processor;
|
package org.mapstruct.ap.internal.processor;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
|
|
||||||
@ -25,6 +27,8 @@ import javax.lang.model.element.TypeElement;
|
|||||||
|
|
||||||
import org.mapstruct.ap.internal.model.Annotation;
|
import org.mapstruct.ap.internal.model.Annotation;
|
||||||
import org.mapstruct.ap.internal.model.AnnotationMapperReference;
|
import org.mapstruct.ap.internal.model.AnnotationMapperReference;
|
||||||
|
import org.mapstruct.ap.internal.model.Decorator;
|
||||||
|
import org.mapstruct.ap.internal.model.Field;
|
||||||
import org.mapstruct.ap.internal.model.Mapper;
|
import org.mapstruct.ap.internal.model.Mapper;
|
||||||
import org.mapstruct.ap.internal.model.MapperReference;
|
import org.mapstruct.ap.internal.model.MapperReference;
|
||||||
import org.mapstruct.ap.internal.model.common.TypeFactory;
|
import org.mapstruct.ap.internal.model.common.TypeFactory;
|
||||||
@ -64,27 +68,55 @@ public abstract class AnnotationBasedComponentModelProcessor implements ModelEle
|
|||||||
if ( !requiresGenerationOfDecoratorClass() ) {
|
if ( !requiresGenerationOfDecoratorClass() ) {
|
||||||
mapper.removeDecorator();
|
mapper.removeDecorator();
|
||||||
}
|
}
|
||||||
|
else if ( mapper.getDecorator() != null ) {
|
||||||
|
adjustDecorator( mapper );
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Annotation> annotations = getMapperReferenceAnnotations();
|
||||||
ListIterator<MapperReference> iterator = mapper.getReferencedMappers().listIterator();
|
ListIterator<MapperReference> iterator = mapper.getReferencedMappers().listIterator();
|
||||||
while ( iterator.hasNext() ) {
|
while ( iterator.hasNext() ) {
|
||||||
MapperReference reference = iterator.next();
|
MapperReference reference = iterator.next();
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
iterator.add( replacementMapperReference( reference ) );
|
iterator.add( replacementMapperReference( reference, annotations ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return mapper;
|
return mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void adjustDecorator(Mapper mapper) {
|
||||||
|
Decorator decorator = mapper.getDecorator();
|
||||||
|
|
||||||
|
for ( Annotation typeAnnotation : getDecoratorAnnotations() ) {
|
||||||
|
decorator.addAnnotation( typeAnnotation );
|
||||||
|
}
|
||||||
|
|
||||||
|
decorator.removeConstructor();
|
||||||
|
|
||||||
|
|
||||||
|
List<Annotation> annotations = getDelegatorReferenceAnnotations( mapper );
|
||||||
|
List<Field> replacement = new ArrayList<Field>();
|
||||||
|
if ( !decorator.getMethods().isEmpty() ) {
|
||||||
|
for ( Field field : decorator.getFields() ) {
|
||||||
|
replacement.add( replacementMapperReference( field, annotations ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
decorator.setFields( replacement );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<Annotation> getDelegatorReferenceAnnotations(Mapper mapper) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param originalReference the reference to be replaced
|
* @param originalReference the reference to be replaced
|
||||||
*
|
*
|
||||||
* @return the mapper reference replacing the original one
|
* @return the mapper reference replacing the original one
|
||||||
*/
|
*/
|
||||||
protected MapperReference replacementMapperReference(MapperReference originalReference) {
|
protected MapperReference replacementMapperReference(Field originalReference, List<Annotation> annotations) {
|
||||||
return new AnnotationMapperReference(
|
return new AnnotationMapperReference(
|
||||||
originalReference.getType(),
|
originalReference.getType(),
|
||||||
originalReference.getVariableName(),
|
originalReference.getVariableName(),
|
||||||
getMapperReferenceAnnotation(),
|
annotations,
|
||||||
originalReference.isUsed()
|
originalReference.isUsed()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -99,10 +131,17 @@ public abstract class AnnotationBasedComponentModelProcessor implements ModelEle
|
|||||||
*/
|
*/
|
||||||
protected abstract List<Annotation> getTypeAnnotations(Mapper mapper);
|
protected abstract List<Annotation> getTypeAnnotations(Mapper mapper);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the annotation(s) to be added at the decorator of the mapper
|
||||||
|
*/
|
||||||
|
protected List<Annotation> getDecoratorAnnotations() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the annotation of the field for the mapper reference
|
* @return the annotation of the field for the mapper reference
|
||||||
*/
|
*/
|
||||||
protected abstract Annotation getMapperReferenceAnnotation();
|
protected abstract List<Annotation> getMapperReferenceAnnotations();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return if a decorator (sub-)class needs to be generated or not
|
* @return if a decorator (sub-)class needs to be generated or not
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.internal.processor;
|
package org.mapstruct.ap.internal.processor;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -46,8 +47,8 @@ public class CdiComponentProcessor extends AnnotationBasedComponentModelProcesso
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Annotation getMapperReferenceAnnotation() {
|
protected List<Annotation> getMapperReferenceAnnotations() {
|
||||||
return new Annotation( getTypeFactory().getType( "javax.inject.Inject" ) );
|
return Arrays.asList( new Annotation( getTypeFactory().getType( "javax.inject.Inject" ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -18,11 +18,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.internal.processor;
|
package org.mapstruct.ap.internal.processor;
|
||||||
|
|
||||||
import org.mapstruct.ap.internal.model.Annotation;
|
import java.util.Arrays;
|
||||||
import org.mapstruct.ap.internal.model.Mapper;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.mapstruct.ap.internal.model.Annotation;
|
||||||
|
import org.mapstruct.ap.internal.model.Mapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link ModelElementProcessor} which converts the given {@link Mapper}
|
* A {@link ModelElementProcessor} which converts the given {@link Mapper}
|
||||||
* object into a JSR 330 style bean in case "jsr330" is configured as the
|
* object into a JSR 330 style bean in case "jsr330" is configured as the
|
||||||
@ -39,16 +41,46 @@ public class Jsr330ComponentProcessor extends AnnotationBasedComponentModelProce
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<Annotation> getTypeAnnotations(Mapper mapper) {
|
protected List<Annotation> getTypeAnnotations(Mapper mapper) {
|
||||||
return Collections.singletonList( new Annotation( getTypeFactory().getType( "javax.inject.Named" ) ) );
|
if ( mapper.getDecorator() == null ) {
|
||||||
|
return Collections.singletonList( named() );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return Collections.singletonList( namedDelegate( mapper ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Annotation getMapperReferenceAnnotation() {
|
protected List<Annotation> getDecoratorAnnotations() {
|
||||||
return new Annotation( getTypeFactory().getType( "javax.inject.Inject" ) );
|
return Collections.singletonList( named() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<Annotation> getDelegatorReferenceAnnotations(Mapper mapper) {
|
||||||
|
return Arrays.asList( inject(), namedDelegate( mapper ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<Annotation> getMapperReferenceAnnotations() {
|
||||||
|
return Collections.singletonList( inject() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean requiresGenerationOfDecoratorClass() {
|
protected boolean requiresGenerationOfDecoratorClass() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Annotation named() {
|
||||||
|
return new Annotation( getTypeFactory().getType( "javax.inject.Named" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private Annotation namedDelegate(Mapper mapper) {
|
||||||
|
return new Annotation(
|
||||||
|
getTypeFactory().getType( "javax.inject.Named" ),
|
||||||
|
Collections.singletonList( '"' + mapper.getPackageName() + "." + mapper.getName() + '"' )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Annotation inject() {
|
||||||
|
return new Annotation( getTypeFactory().getType( "javax.inject.Inject" ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ package org.mapstruct.ap.internal.processor;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.mapstruct.ap.internal.model.Annotation;
|
import org.mapstruct.ap.internal.model.Annotation;
|
||||||
@ -42,26 +43,58 @@ public class SpringComponentProcessor extends AnnotationBasedComponentModelProce
|
|||||||
@Override
|
@Override
|
||||||
protected List<Annotation> getTypeAnnotations(Mapper mapper) {
|
protected List<Annotation> getTypeAnnotations(Mapper mapper) {
|
||||||
List<Annotation> typeAnnotations = new ArrayList<Annotation>();
|
List<Annotation> typeAnnotations = new ArrayList<Annotation>();
|
||||||
typeAnnotations.add( new Annotation( getTypeFactory().getType( "org.springframework.stereotype.Component" ) ) );
|
typeAnnotations.add( component() );
|
||||||
|
|
||||||
if ( mapper.getDecorator() != null ) {
|
if ( mapper.getDecorator() != null ) {
|
||||||
Annotation qualifier = new Annotation(
|
typeAnnotations.add( qualifierDelegate() );
|
||||||
getTypeFactory().getType( "org.springframework.beans.factory.annotation.Qualifier" ),
|
|
||||||
Arrays.asList( "\"delegate\"" )
|
|
||||||
);
|
|
||||||
typeAnnotations.add( qualifier );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return typeAnnotations;
|
return typeAnnotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Annotation getMapperReferenceAnnotation() {
|
protected List<Annotation> getDecoratorAnnotations() {
|
||||||
return new Annotation( getTypeFactory().getType( "org.springframework.beans.factory.annotation.Autowired" ) );
|
return Arrays.asList(
|
||||||
|
component(),
|
||||||
|
primary()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<Annotation> getMapperReferenceAnnotations() {
|
||||||
|
return Collections.singletonList(
|
||||||
|
autowired()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<Annotation> getDelegatorReferenceAnnotations(Mapper mapper) {
|
||||||
|
return Arrays.asList(
|
||||||
|
autowired(),
|
||||||
|
qualifierDelegate()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean requiresGenerationOfDecoratorClass() {
|
protected boolean requiresGenerationOfDecoratorClass() {
|
||||||
return false;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Annotation autowired() {
|
||||||
|
return new Annotation( getTypeFactory().getType( "org.springframework.beans.factory.annotation.Autowired" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private Annotation qualifierDelegate() {
|
||||||
|
return new Annotation(
|
||||||
|
getTypeFactory().getType( "org.springframework.beans.factory.annotation.Qualifier" ),
|
||||||
|
Collections.singletonList( "\"delegate\"" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private Annotation primary() {
|
||||||
|
return new Annotation( getTypeFactory().getType( "org.springframework.context.annotation.Primary" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private Annotation component() {
|
||||||
|
return new Annotation( getTypeFactory().getType( "org.springframework.stereotype.Component" ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,5 +18,7 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
<#list annotations as annotation>
|
||||||
<#nt><@includeModel object=annotation/>
|
<#nt><@includeModel object=annotation/>
|
||||||
|
</#list>
|
||||||
private <@includeModel object=type/> ${variableName};
|
private <@includeModel object=type/> ${variableName};
|
@ -0,0 +1,110 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||||
|
* and/or other contributors as indicated by the @authors tag. See the
|
||||||
|
* copyright.txt file in the distribution for a full listing of all
|
||||||
|
* contributors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.mapstruct.ap.test.decorator.jsr330;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mapstruct.ap.test.decorator.Address;
|
||||||
|
import org.mapstruct.ap.test.decorator.AddressDto;
|
||||||
|
import org.mapstruct.ap.test.decorator.Person;
|
||||||
|
import org.mapstruct.ap.test.decorator.PersonDto;
|
||||||
|
import org.mapstruct.ap.testutil.IssueKey;
|
||||||
|
import org.mapstruct.ap.testutil.WithClasses;
|
||||||
|
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
|
||||||
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import static org.fest.assertions.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for the application of decorators using component model jsr330.
|
||||||
|
*
|
||||||
|
* @author Andreas Gudian
|
||||||
|
*/
|
||||||
|
@WithClasses({
|
||||||
|
Person.class,
|
||||||
|
PersonDto.class,
|
||||||
|
Address.class,
|
||||||
|
AddressDto.class,
|
||||||
|
PersonMapper.class,
|
||||||
|
PersonMapperDecorator.class
|
||||||
|
})
|
||||||
|
@IssueKey("592")
|
||||||
|
@RunWith(AnnotationProcessorTestRunner.class)
|
||||||
|
@ComponentScan(basePackageClasses = Jsr330DecoratorTest.class)
|
||||||
|
@Configuration
|
||||||
|
public class Jsr330DecoratorTest {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Named
|
||||||
|
private PersonMapper personMapper;
|
||||||
|
private ConfigurableApplicationContext context;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void springUp() {
|
||||||
|
context = new AnnotationConfigApplicationContext( getClass() );
|
||||||
|
context.getAutowireCapableBeanFactory().autowireBean( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void springDown() {
|
||||||
|
if ( context != null ) {
|
||||||
|
context.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
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.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
|
||||||
|
public void shouldDelegateNonDecoratedMethodsToDefaultImplementation() {
|
||||||
|
//given
|
||||||
|
Address address = new Address( "42 Ocean View Drive" );
|
||||||
|
|
||||||
|
//when
|
||||||
|
AddressDto addressDto = personMapper.addressToAddressDto( address );
|
||||||
|
|
||||||
|
//then
|
||||||
|
assertThat( addressDto ).isNotNull();
|
||||||
|
assertThat( addressDto.getAddressLine() ).isEqualTo( "42 Ocean View Drive" );
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||||
|
* and/or other contributors as indicated by the @authors tag. See the
|
||||||
|
* copyright.txt file in the distribution for a full listing of all
|
||||||
|
* contributors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.mapstruct.ap.test.decorator.jsr330;
|
||||||
|
|
||||||
|
import org.mapstruct.DecoratedWith;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.Mapping;
|
||||||
|
import org.mapstruct.ap.test.decorator.Address;
|
||||||
|
import org.mapstruct.ap.test.decorator.AddressDto;
|
||||||
|
import org.mapstruct.ap.test.decorator.Person;
|
||||||
|
import org.mapstruct.ap.test.decorator.PersonDto;
|
||||||
|
|
||||||
|
@Mapper(componentModel = "jsr330")
|
||||||
|
@DecoratedWith(PersonMapperDecorator.class)
|
||||||
|
public interface PersonMapper {
|
||||||
|
|
||||||
|
@Mapping( target = "name", ignore = true )
|
||||||
|
PersonDto personToPersonDto(Person person);
|
||||||
|
|
||||||
|
AddressDto addressToAddressDto(Address address);
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||||
|
* and/or other contributors as indicated by the @authors tag. See the
|
||||||
|
* copyright.txt file in the distribution for a full listing of all
|
||||||
|
* contributors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.mapstruct.ap.test.decorator.jsr330;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
|
import org.mapstruct.ap.test.decorator.Person;
|
||||||
|
import org.mapstruct.ap.test.decorator.PersonDto;
|
||||||
|
|
||||||
|
public abstract class PersonMapperDecorator implements PersonMapper {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Named("org.mapstruct.ap.test.decorator.jsr330.PersonMapperImpl_")
|
||||||
|
private PersonMapper delegate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PersonDto personToPersonDto(Person person) {
|
||||||
|
PersonDto dto = delegate.personToPersonDto( person );
|
||||||
|
dto.setName( person.getFirstName() + " " + person.getLastName() );
|
||||||
|
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||||
|
* and/or other contributors as indicated by the @authors tag. See the
|
||||||
|
* copyright.txt file in the distribution for a full listing of all
|
||||||
|
* contributors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.mapstruct.ap.test.decorator.spring;
|
||||||
|
|
||||||
|
import org.mapstruct.DecoratedWith;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.Mapping;
|
||||||
|
import org.mapstruct.ap.test.decorator.Address;
|
||||||
|
import org.mapstruct.ap.test.decorator.AddressDto;
|
||||||
|
import org.mapstruct.ap.test.decorator.Person;
|
||||||
|
import org.mapstruct.ap.test.decorator.PersonDto;
|
||||||
|
|
||||||
|
@Mapper(componentModel = "spring")
|
||||||
|
@DecoratedWith(PersonMapperDecorator.class)
|
||||||
|
public interface PersonMapper {
|
||||||
|
|
||||||
|
@Mapping( target = "name", ignore = true )
|
||||||
|
PersonDto personToPersonDto(Person person);
|
||||||
|
|
||||||
|
AddressDto addressToAddressDto(Address address);
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||||
|
* and/or other contributors as indicated by the @authors tag. See the
|
||||||
|
* copyright.txt file in the distribution for a full listing of all
|
||||||
|
* contributors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.mapstruct.ap.test.decorator.spring;
|
||||||
|
|
||||||
|
import org.mapstruct.ap.test.decorator.Person;
|
||||||
|
import org.mapstruct.ap.test.decorator.PersonDto;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
|
||||||
|
public abstract class PersonMapperDecorator implements PersonMapper {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Qualifier("delegate")
|
||||||
|
private PersonMapper delegate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PersonDto personToPersonDto(Person person) {
|
||||||
|
PersonDto dto = delegate.personToPersonDto( person );
|
||||||
|
dto.setName( person.getFirstName() + " " + person.getLastName() );
|
||||||
|
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,107 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||||
|
* and/or other contributors as indicated by the @authors tag. See the
|
||||||
|
* copyright.txt file in the distribution for a full listing of all
|
||||||
|
* contributors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.mapstruct.ap.test.decorator.spring;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mapstruct.ap.test.decorator.Address;
|
||||||
|
import org.mapstruct.ap.test.decorator.AddressDto;
|
||||||
|
import org.mapstruct.ap.test.decorator.Person;
|
||||||
|
import org.mapstruct.ap.test.decorator.PersonDto;
|
||||||
|
import org.mapstruct.ap.testutil.IssueKey;
|
||||||
|
import org.mapstruct.ap.testutil.WithClasses;
|
||||||
|
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import static org.fest.assertions.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for the application of decorators using component model spring.
|
||||||
|
*
|
||||||
|
* @author Andreas Gudian
|
||||||
|
*/
|
||||||
|
@WithClasses({
|
||||||
|
Person.class,
|
||||||
|
PersonDto.class,
|
||||||
|
Address.class,
|
||||||
|
AddressDto.class,
|
||||||
|
PersonMapper.class,
|
||||||
|
PersonMapperDecorator.class
|
||||||
|
})
|
||||||
|
@IssueKey("592")
|
||||||
|
@RunWith(AnnotationProcessorTestRunner.class)
|
||||||
|
@ComponentScan(basePackageClasses = SpringDecoratorTest.class)
|
||||||
|
@Configuration
|
||||||
|
public class SpringDecoratorTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PersonMapper personMapper;
|
||||||
|
private ConfigurableApplicationContext context;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void springUp() {
|
||||||
|
context = new AnnotationConfigApplicationContext( getClass() );
|
||||||
|
context.getAutowireCapableBeanFactory().autowireBean( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void springDown() {
|
||||||
|
if ( context != null ) {
|
||||||
|
context.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
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.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
|
||||||
|
public void shouldDelegateNonDecoratedMethodsToDefaultImplementation() {
|
||||||
|
//given
|
||||||
|
Address address = new Address( "42 Ocean View Drive" );
|
||||||
|
|
||||||
|
//when
|
||||||
|
AddressDto addressDto = personMapper.addressToAddressDto( address );
|
||||||
|
|
||||||
|
//then
|
||||||
|
assertThat( addressDto ).isNotNull();
|
||||||
|
assertThat( addressDto.getAddressLine() ).isEqualTo( "42 Ocean View Drive" );
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user