Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion core/src/main/java/org/mapstruct/MappingConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,12 @@ private ComponentModel() {
public static final String DEFAULT = "default";

/**
* The generated mapper is an application-scoped CDI bean and can be retrieved via @Inject
* The generated mapper is an application-scoped CDI bean and can be retrieved via @Inject.
* The annotations are either from {@code javax} or {@code jakarta}.
* Priority have the {@code javax} annotations.
* In case you want to only use Jakarta then use {@link #JAKARTA_CDI}.
*
* @see #JAKARTA_CDI
*/
public static final String CDI = "cdi";

Expand Down Expand Up @@ -138,6 +143,12 @@ private ComponentModel() {
*/
public static final String JAKARTA = "jakarta";

/**
* The generated mapper is an application-scoped Jakarta CDI bean and can be retrieved via @Inject.
* @see #CDI
*/
public static final String JAKARTA_CDI = "jakarta-cdi";

}

}
4 changes: 4 additions & 0 deletions integrationtest/src/test/resources/fullFeatureTest/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@
<groupId>jakarta.inject</groupId>
<artifactId>jakarta.inject-api</artifactId>
</dependency>
<dependency>
<groupId>jakarta.enterprise</groupId>
<artifactId>jakarta.enterprise.cdi-api</artifactId>
</dependency>

<!-- Spring -->
<dependency>
Expand Down
5 changes: 5 additions & 0 deletions parent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,11 @@
<artifactId>cdi-api</artifactId>
<version>2.0.SP1</version>
</dependency>
<dependency>
<groupId>jakarta.enterprise</groupId>
<artifactId>jakarta.enterprise.cdi-api</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
Expand Down
5 changes: 5 additions & 0 deletions processor/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@
<artifactId>jakarta.inject-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jakarta.enterprise</groupId>
<artifactId>jakarta.enterprise.cdi-api</artifactId>
<scope>test</scope>
</dependency>

<!-- plexus-container-default is a runtime-dependency of the tycho-compiler -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ private ComponentModelGem() {
public static final String JSR330 = "jsr330";

public static final String JAKARTA = "jakarta";

public static final String JAKARTA_CDI = "jakarta-cdi";
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import org.mapstruct.ap.internal.gem.MappingConstantsGem;
import org.mapstruct.ap.internal.model.Annotation;
import org.mapstruct.ap.internal.model.Mapper;
import org.mapstruct.ap.internal.model.common.Type;
import org.mapstruct.ap.internal.util.AnnotationProcessingException;

/**
* A {@link ModelElementProcessor} which converts the given {@link Mapper}
Expand All @@ -30,13 +32,13 @@ protected String getComponentModelIdentifier() {
@Override
protected List<Annotation> getTypeAnnotations(Mapper mapper) {
return Collections.singletonList(
new Annotation( getTypeFactory().getType( "javax.enterprise.context.ApplicationScoped" ) )
new Annotation( getType( "ApplicationScoped" ) )
);
}

@Override
protected List<Annotation> getMapperReferenceAnnotations() {
return Arrays.asList( new Annotation( getTypeFactory().getType( "javax.inject.Inject" ) ) );
return Arrays.asList( new Annotation( getType( "Inject" ) ) );
}

@Override
Expand All @@ -48,4 +50,24 @@ protected boolean requiresGenerationOfDecoratorClass() {
protected boolean additionalPublicEmptyConstructor() {
return true;
}

private Type getType(String simpleName) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getCDIType

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't want to complicate things. This also fetches the @Inject from the inject package as well

String javaxPrefix = "javax.inject.";
String jakartaPrefix = "jakarta.inject.";
if ( "ApplicationScoped".equals( simpleName ) ) {
javaxPrefix = "javax.enterprise.context.";
jakartaPrefix = "jakarta.enterprise.context.";
}
if ( getTypeFactory().isTypeAvailable( javaxPrefix + simpleName ) ) {
return getTypeFactory().getType( javaxPrefix + simpleName );
}

if ( getTypeFactory().isTypeAvailable( jakartaPrefix + simpleName ) ) {
return getTypeFactory().getType( jakartaPrefix + simpleName );
}

throw new AnnotationProcessingException(
"Couldn't find any of the CDI or Jakarta CDI Dependency types." +
" Are you missing a dependency on your classpath?" );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright MapStruct Authors.
*
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/
package org.mapstruct.ap.internal.processor;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.mapstruct.ap.internal.gem.MappingConstantsGem;
import org.mapstruct.ap.internal.model.Annotation;
import org.mapstruct.ap.internal.model.Mapper;

/**
* A {@link ModelElementProcessor} which converts the given {@link Mapper}
* object into an application-scoped Jakarta CDI bean in case Jakarta CDI
* is configured as the target component model for this mapper.
*
* @author Filip Hrisafov
*/
public class JakartaCdiComponentProcessor extends AnnotationBasedComponentModelProcessor {

@Override
protected String getComponentModelIdentifier() {
return MappingConstantsGem.ComponentModelGem.JAKARTA_CDI;
}

@Override
protected List<Annotation> getTypeAnnotations(Mapper mapper) {
return Collections.singletonList(
new Annotation( getTypeFactory().getType( "jakarta.enterprise.context.ApplicationScoped" ) )
);
}

@Override
protected List<Annotation> getMapperReferenceAnnotations() {
return Arrays.asList( new Annotation( getTypeFactory().getType( "jakarta.inject.Inject" ) ) );
}

@Override
protected boolean requiresGenerationOfDecoratorClass() {
return false;
}

@Override
protected boolean additionalPublicEmptyConstructor() {
return true;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0

org.mapstruct.ap.internal.processor.CdiComponentProcessor
org.mapstruct.ap.internal.processor.JakartaCdiComponentProcessor
org.mapstruct.ap.internal.processor.Jsr330ComponentProcessor
org.mapstruct.ap.internal.processor.JakartaComponentProcessor
org.mapstruct.ap.internal.processor.MapperCreationProcessor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,15 @@ public void constantsShouldBeEqual() {
}

@Test
public void componentModelContantsShouldBeEqual() {
public void componentModelConstantsShouldBeEqual() {
assertThat( MappingConstants.ComponentModel.DEFAULT )
.isEqualTo( MappingConstantsGem.ComponentModelGem.DEFAULT );
assertThat( MappingConstants.ComponentModel.CDI ).isEqualTo( MappingConstantsGem.ComponentModelGem.CDI );
assertThat( MappingConstants.ComponentModel.SPRING ).isEqualTo( MappingConstantsGem.ComponentModelGem.SPRING );
assertThat( MappingConstants.ComponentModel.JSR330 ).isEqualTo( MappingConstantsGem.ComponentModelGem.JSR330 );
assertThat( MappingConstants.ComponentModel.JAKARTA )
.isEqualTo( MappingConstantsGem.ComponentModelGem.JAKARTA );
assertThat( MappingConstants.ComponentModel.JAKARTA_CDI )
.isEqualTo( MappingConstantsGem.ComponentModelGem.JAKARTA_CDI );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright MapStruct Authors.
*
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/
package org.mapstruct.ap.test.injectionstrategy.cdi._default;

import org.junit.jupiter.api.extension.RegisterExtension;
import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto;
import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity;
import org.mapstruct.ap.test.injectionstrategy.shared.Gender;
import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto;
import org.mapstruct.ap.testutil.IssueKey;
import org.mapstruct.ap.testutil.ProcessorTest;
import org.mapstruct.ap.testutil.WithCdi;
import org.mapstruct.ap.testutil.WithClasses;
import org.mapstruct.ap.testutil.runner.GeneratedSource;

import static java.lang.System.lineSeparator;

/**
* Test field injection for component model jakarta-cdi.
* Default value option mapstruct.defaultInjectionStrategy is "field"
*
* @author Filip Hrisafov
*/
@IssueKey("2950")
@WithClasses({
CustomerDto.class,
CustomerEntity.class,
Gender.class,
GenderDto.class,
CustomerCdiDefaultCompileOptionFieldMapper.class,
GenderCdiDefaultCompileOptionFieldMapper.class
})
@WithCdi
public class CdiDefaultCompileOptionFieldMapperTest {

@RegisterExtension
final GeneratedSource generatedSource = new GeneratedSource();

@ProcessorTest
public void shouldHaveFieldInjection() {
generatedSource.forMapper( CustomerCdiDefaultCompileOptionFieldMapper.class )
.content()
.contains( "import javax.enterprise.context.ApplicationScoped;" )
.contains( "import javax.inject.Inject;" )
.contains( "@Inject" + lineSeparator() + " private GenderCdiDefaultCompileOptionFieldMapper" )
.contains( "@ApplicationScoped" + lineSeparator() + "public class" )
.doesNotContain( "public CustomerCdiDefaultCompileOptionFieldMapperImpl(" )
.doesNotContain( "jakarta.inject" )
.doesNotContain( "jakarta.enterprise" );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright MapStruct Authors.
*
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/
package org.mapstruct.ap.test.injectionstrategy.cdi._default;

import org.mapstruct.Mapper;
import org.mapstruct.MappingConstants;
import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto;
import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity;

/**
* @author Filip Hrisafov
*/
@Mapper(componentModel = MappingConstants.ComponentModel.CDI,
uses = GenderCdiDefaultCompileOptionFieldMapper.class)
public interface CustomerCdiDefaultCompileOptionFieldMapper {

CustomerDto asTarget(CustomerEntity customerEntity);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright MapStruct Authors.
*
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/
package org.mapstruct.ap.test.injectionstrategy.cdi._default;

import org.mapstruct.Mapper;
import org.mapstruct.MappingConstants;
import org.mapstruct.ValueMapping;
import org.mapstruct.ValueMappings;
import org.mapstruct.ap.test.injectionstrategy.shared.Gender;
import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto;

/**
* @author Filip Hrisafov
*/
@Mapper(componentModel = MappingConstants.ComponentModel.CDI)
public interface GenderCdiDefaultCompileOptionFieldMapper {

@ValueMappings({
@ValueMapping(source = "MALE", target = "M"),
@ValueMapping(source = "FEMALE", target = "F")
})
GenderDto mapToDto(Gender gender);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright MapStruct Authors.
*
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/
package org.mapstruct.ap.test.injectionstrategy.cdi.jakarta;

import org.mapstruct.Mapper;
import org.mapstruct.MappingConstants;
import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto;
import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity;

/**
* @author Filip Hrisafov
*/
@Mapper(componentModel = MappingConstants.ComponentModel.CDI,
uses = GenderCdiDefaultCompileOptionFieldMapper.class)
public interface CustomerCdiDefaultCompileOptionFieldMapper {

CustomerDto asTarget(CustomerEntity customerEntity);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright MapStruct Authors.
*
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/
package org.mapstruct.ap.test.injectionstrategy.cdi.jakarta;

import org.mapstruct.Mapper;
import org.mapstruct.MappingConstants;
import org.mapstruct.ValueMapping;
import org.mapstruct.ValueMappings;
import org.mapstruct.ap.test.injectionstrategy.shared.Gender;
import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto;

/**
* @author Filip Hrisafov
*/
@Mapper(componentModel = MappingConstants.ComponentModel.CDI)
public interface GenderCdiDefaultCompileOptionFieldMapper {

@ValueMappings({
@ValueMapping(source = "MALE", target = "M"),
@ValueMapping(source = "FEMALE", target = "F")
})
GenderDto mapToDto(Gender gender);
}
Loading