org.mapstruct.ap.internal.gem.MappingGem Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mapstruct-processor Show documentation
Show all versions of mapstruct-processor Show documentation
An annotation processor for generating type-safe bean mappers
package org.mapstruct.ap.internal.gem;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.AbstractAnnotationValueVisitor8;
import javax.lang.model.util.ElementFilter;
import org.mapstruct.tools.gem.Gem;
import org.mapstruct.tools.gem.GemValue;
import javax.lang.model.type.TypeMirror;
public class MappingGem implements Gem {
private final GemValue target;
private final GemValue source;
private final GemValue dateFormat;
private final GemValue numberFormat;
private final GemValue constant;
private final GemValue expression;
private final GemValue defaultExpression;
private final GemValue ignore;
private final GemValue> qualifiedBy;
private final GemValue> qualifiedByName;
private final GemValue resultType;
private final GemValue> dependsOn;
private final GemValue defaultValue;
private final GemValue nullValueCheckStrategy;
private final GemValue nullValuePropertyMappingStrategy;
private final GemValue mappingControl;
private final boolean isValid;
private final AnnotationMirror mirror;
private MappingGem( BuilderImpl builder ) {
this.target = builder.target;
this.source = builder.source;
this.dateFormat = builder.dateFormat;
this.numberFormat = builder.numberFormat;
this.constant = builder.constant;
this.expression = builder.expression;
this.defaultExpression = builder.defaultExpression;
this.ignore = builder.ignore;
this.qualifiedBy = builder.qualifiedBy;
this.qualifiedByName = builder.qualifiedByName;
this.resultType = builder.resultType;
this.dependsOn = builder.dependsOn;
this.defaultValue = builder.defaultValue;
this.nullValueCheckStrategy = builder.nullValueCheckStrategy;
this.nullValuePropertyMappingStrategy = builder.nullValuePropertyMappingStrategy;
this.mappingControl = builder.mappingControl;
isValid = ( this.target != null ? this.target.isValid() : false )
&& ( this.source != null ? this.source.isValid() : false )
&& ( this.dateFormat != null ? this.dateFormat.isValid() : false )
&& ( this.numberFormat != null ? this.numberFormat.isValid() : false )
&& ( this.constant != null ? this.constant.isValid() : false )
&& ( this.expression != null ? this.expression.isValid() : false )
&& ( this.defaultExpression != null ? this.defaultExpression.isValid() : false )
&& ( this.ignore != null ? this.ignore.isValid() : false )
&& ( this.qualifiedBy != null ? this.qualifiedBy.isValid() : false )
&& ( this.qualifiedByName != null ? this.qualifiedByName.isValid() : false )
&& ( this.resultType != null ? this.resultType.isValid() : false )
&& ( this.dependsOn != null ? this.dependsOn.isValid() : false )
&& ( this.defaultValue != null ? this.defaultValue.isValid() : false )
&& ( this.nullValueCheckStrategy != null ? this.nullValueCheckStrategy.isValid() : false )
&& ( this.nullValuePropertyMappingStrategy != null ? this.nullValuePropertyMappingStrategy.isValid() : false )
&& ( this.mappingControl != null ? this.mappingControl.isValid() : false );
mirror = builder.mirror;
}
/**
* accessor
*
* @return the {@link GemValue} for {@link MappingGem#target}
*/
public GemValue target( ) {
return target;
}
/**
* accessor
*
* @return the {@link GemValue} for {@link MappingGem#source}
*/
public GemValue source( ) {
return source;
}
/**
* accessor
*
* @return the {@link GemValue} for {@link MappingGem#dateFormat}
*/
public GemValue dateFormat( ) {
return dateFormat;
}
/**
* accessor
*
* @return the {@link GemValue} for {@link MappingGem#numberFormat}
*/
public GemValue numberFormat( ) {
return numberFormat;
}
/**
* accessor
*
* @return the {@link GemValue} for {@link MappingGem#constant}
*/
public GemValue constant( ) {
return constant;
}
/**
* accessor
*
* @return the {@link GemValue} for {@link MappingGem#expression}
*/
public GemValue expression( ) {
return expression;
}
/**
* accessor
*
* @return the {@link GemValue} for {@link MappingGem#defaultExpression}
*/
public GemValue defaultExpression( ) {
return defaultExpression;
}
/**
* accessor
*
* @return the {@link GemValue} for {@link MappingGem#ignore}
*/
public GemValue ignore( ) {
return ignore;
}
/**
* accessor
*
* @return the {@link GemValue} for {@link MappingGem#qualifiedBy}
*/
public GemValue> qualifiedBy( ) {
return qualifiedBy;
}
/**
* accessor
*
* @return the {@link GemValue} for {@link MappingGem#qualifiedByName}
*/
public GemValue> qualifiedByName( ) {
return qualifiedByName;
}
/**
* accessor
*
* @return the {@link GemValue} for {@link MappingGem#resultType}
*/
public GemValue resultType( ) {
return resultType;
}
/**
* accessor
*
* @return the {@link GemValue} for {@link MappingGem#dependsOn}
*/
public GemValue> dependsOn( ) {
return dependsOn;
}
/**
* accessor
*
* @return the {@link GemValue} for {@link MappingGem#defaultValue}
*/
public GemValue defaultValue( ) {
return defaultValue;
}
/**
* accessor
*
* @return the {@link GemValue} for {@link MappingGem#nullValueCheckStrategy}
*/
public GemValue nullValueCheckStrategy( ) {
return nullValueCheckStrategy;
}
/**
* accessor
*
* @return the {@link GemValue} for {@link MappingGem#nullValuePropertyMappingStrategy}
*/
public GemValue nullValuePropertyMappingStrategy( ) {
return nullValuePropertyMappingStrategy;
}
/**
* accessor
*
* @return the {@link GemValue} for {@link MappingGem#mappingControl}
*/
public GemValue mappingControl( ) {
return mappingControl;
}
@Override
public AnnotationMirror mirror( ) {
return mirror;
}
@Override
public boolean isValid( ) {
return isValid;
}
public static MappingGem instanceOn(Element element) {
return build( element, new BuilderImpl() );
}
public static MappingGem instanceOn(AnnotationMirror mirror ) {
return build( mirror, new BuilderImpl() );
}
public static T build(Element element, Builder builder) {
AnnotationMirror mirror = element.getAnnotationMirrors().stream()
.filter( a -> "org.mapstruct.Mapping".contentEquals( ( ( TypeElement )a.getAnnotationType().asElement() ).getQualifiedName() ) )
.findAny()
.orElse( null );
return build( mirror, builder );
}
public static T build(AnnotationMirror mirror, Builder builder ) {
// return fast
if ( mirror == null || builder == null ) {
return null;
}
// fetch defaults from all defined values in the annotation type
List enclosed = ElementFilter.methodsIn( mirror.getAnnotationType().asElement().getEnclosedElements() );
Map defaultValues = new HashMap<>( enclosed.size() );
enclosed.forEach( e -> defaultValues.put( e.getSimpleName().toString(), e.getDefaultValue() ) );
// fetch all explicitely set annotation values in the annotation instance
Map values = new HashMap<>( enclosed.size() );
mirror.getElementValues().entrySet().forEach( e -> values.put( e.getKey().getSimpleName().toString(), e.getValue() ) );
// iterate and populate builder
for ( String methodName : defaultValues.keySet() ) {
if ( "target".equals( methodName ) ) {
builder.setTarget( GemValue.create( values.get( methodName ), defaultValues.get( methodName ), String.class ) );
}
else if ( "source".equals( methodName ) ) {
builder.setSource( GemValue.create( values.get( methodName ), defaultValues.get( methodName ), String.class ) );
}
else if ( "dateFormat".equals( methodName ) ) {
builder.setDateformat( GemValue.create( values.get( methodName ), defaultValues.get( methodName ), String.class ) );
}
else if ( "numberFormat".equals( methodName ) ) {
builder.setNumberformat( GemValue.create( values.get( methodName ), defaultValues.get( methodName ), String.class ) );
}
else if ( "constant".equals( methodName ) ) {
builder.setConstant( GemValue.create( values.get( methodName ), defaultValues.get( methodName ), String.class ) );
}
else if ( "expression".equals( methodName ) ) {
builder.setExpression( GemValue.create( values.get( methodName ), defaultValues.get( methodName ), String.class ) );
}
else if ( "defaultExpression".equals( methodName ) ) {
builder.setDefaultexpression( GemValue.create( values.get( methodName ), defaultValues.get( methodName ), String.class ) );
}
else if ( "ignore".equals( methodName ) ) {
builder.setIgnore( GemValue.create( values.get( methodName ), defaultValues.get( methodName ), Boolean.class ) );
}
else if ( "qualifiedBy".equals( methodName ) ) {
builder.setQualifiedby( GemValue.createArray( values.get( methodName ), defaultValues.get( methodName ), TypeMirror.class ) );
}
else if ( "qualifiedByName".equals( methodName ) ) {
builder.setQualifiedbyname( GemValue.createArray( values.get( methodName ), defaultValues.get( methodName ), String.class ) );
}
else if ( "resultType".equals( methodName ) ) {
builder.setResulttype( GemValue.create( values.get( methodName ), defaultValues.get( methodName ), TypeMirror.class ) );
}
else if ( "dependsOn".equals( methodName ) ) {
builder.setDependson( GemValue.createArray( values.get( methodName ), defaultValues.get( methodName ), String.class ) );
}
else if ( "defaultValue".equals( methodName ) ) {
builder.setDefaultvalue( GemValue.create( values.get( methodName ), defaultValues.get( methodName ), String.class ) );
}
else if ( "nullValueCheckStrategy".equals( methodName ) ) {
builder.setNullvaluecheckstrategy( GemValue.createEnum( values.get( methodName ), defaultValues.get( methodName ) ) );
}
else if ( "nullValuePropertyMappingStrategy".equals( methodName ) ) {
builder.setNullvaluepropertymappingstrategy( GemValue.createEnum( values.get( methodName ), defaultValues.get( methodName ) ) );
}
else if ( "mappingControl".equals( methodName ) ) {
builder.setMappingcontrol( GemValue.create( values.get( methodName ), defaultValues.get( methodName ), TypeMirror.class ) );
}
}
builder.setMirror( mirror );
return builder.build();
}
/**
* A builder that can be implemented by the user to define custom logic e.g. in the
* build method, prior to creating the annotation gem.
*/
public interface Builder {
/**
* Sets the {@link GemValue} for {@link MappingGem#target}
*
* @return the {@link Builder} for this gem, representing {@link MappingGem}
*/
Builder setTarget(GemValue methodName );
/**
* Sets the {@link GemValue} for {@link MappingGem#source}
*
* @return the {@link Builder} for this gem, representing {@link MappingGem}
*/
Builder setSource(GemValue methodName );
/**
* Sets the {@link GemValue} for {@link MappingGem#dateFormat}
*
* @return the {@link Builder} for this gem, representing {@link MappingGem}
*/
Builder setDateformat(GemValue methodName );
/**
* Sets the {@link GemValue} for {@link MappingGem#numberFormat}
*
* @return the {@link Builder} for this gem, representing {@link MappingGem}
*/
Builder setNumberformat(GemValue methodName );
/**
* Sets the {@link GemValue} for {@link MappingGem#constant}
*
* @return the {@link Builder} for this gem, representing {@link MappingGem}
*/
Builder setConstant(GemValue methodName );
/**
* Sets the {@link GemValue} for {@link MappingGem#expression}
*
* @return the {@link Builder} for this gem, representing {@link MappingGem}
*/
Builder setExpression(GemValue methodName );
/**
* Sets the {@link GemValue} for {@link MappingGem#defaultExpression}
*
* @return the {@link Builder} for this gem, representing {@link MappingGem}
*/
Builder setDefaultexpression(GemValue methodName );
/**
* Sets the {@link GemValue} for {@link MappingGem#ignore}
*
* @return the {@link Builder} for this gem, representing {@link MappingGem}
*/
Builder setIgnore(GemValue methodName );
/**
* Sets the {@link GemValue} for {@link MappingGem#qualifiedBy}
*
* @return the {@link Builder} for this gem, representing {@link MappingGem}
*/
Builder setQualifiedby(GemValue> methodName );
/**
* Sets the {@link GemValue} for {@link MappingGem#qualifiedByName}
*
* @return the {@link Builder} for this gem, representing {@link MappingGem}
*/
Builder setQualifiedbyname(GemValue> methodName );
/**
* Sets the {@link GemValue} for {@link MappingGem#resultType}
*
* @return the {@link Builder} for this gem, representing {@link MappingGem}
*/
Builder setResulttype(GemValue methodName );
/**
* Sets the {@link GemValue} for {@link MappingGem#dependsOn}
*
* @return the {@link Builder} for this gem, representing {@link MappingGem}
*/
Builder setDependson(GemValue> methodName );
/**
* Sets the {@link GemValue} for {@link MappingGem#defaultValue}
*
* @return the {@link Builder} for this gem, representing {@link MappingGem}
*/
Builder setDefaultvalue(GemValue methodName );
/**
* Sets the {@link GemValue} for {@link MappingGem#nullValueCheckStrategy}
*
* @return the {@link Builder} for this gem, representing {@link MappingGem}
*/
Builder setNullvaluecheckstrategy(GemValue methodName );
/**
* Sets the {@link GemValue} for {@link MappingGem#nullValuePropertyMappingStrategy}
*
* @return the {@link Builder} for this gem, representing {@link MappingGem}
*/
Builder setNullvaluepropertymappingstrategy(GemValue methodName );
/**
* Sets the {@link GemValue} for {@link MappingGem#mappingControl}
*
* @return the {@link Builder} for this gem, representing {@link MappingGem}
*/
Builder setMappingcontrol(GemValue methodName );
/**
* Sets the annotation mirror
*
* @param mirror the mirror which this gem represents
*
* @return the {@link Builder} for this gem, representing {@link MappingGem}
*/
Builder setMirror( AnnotationMirror mirror );
/**
* The build method can be overriden in a custom custom implementation, which allows
* the user to define his own custom validation on the annotation.
*
* @return the representation of the annotation
*/
T build();
}
private static class BuilderImpl implements Builder {
private GemValue target;
private GemValue source;
private GemValue dateFormat;
private GemValue numberFormat;
private GemValue constant;
private GemValue expression;
private GemValue defaultExpression;
private GemValue ignore;
private GemValue> qualifiedBy;
private GemValue> qualifiedByName;
private GemValue resultType;
private GemValue> dependsOn;
private GemValue defaultValue;
private GemValue nullValueCheckStrategy;
private GemValue nullValuePropertyMappingStrategy;
private GemValue mappingControl;
private AnnotationMirror mirror;
public Builder setTarget(GemValue target ) {
this.target = target;
return this;
}
public Builder setSource(GemValue source ) {
this.source = source;
return this;
}
public Builder setDateformat(GemValue dateFormat ) {
this.dateFormat = dateFormat;
return this;
}
public Builder setNumberformat(GemValue numberFormat ) {
this.numberFormat = numberFormat;
return this;
}
public Builder setConstant(GemValue constant ) {
this.constant = constant;
return this;
}
public Builder setExpression(GemValue expression ) {
this.expression = expression;
return this;
}
public Builder setDefaultexpression(GemValue defaultExpression ) {
this.defaultExpression = defaultExpression;
return this;
}
public Builder setIgnore(GemValue ignore ) {
this.ignore = ignore;
return this;
}
public Builder setQualifiedby(GemValue> qualifiedBy ) {
this.qualifiedBy = qualifiedBy;
return this;
}
public Builder setQualifiedbyname(GemValue> qualifiedByName ) {
this.qualifiedByName = qualifiedByName;
return this;
}
public Builder setResulttype(GemValue resultType ) {
this.resultType = resultType;
return this;
}
public Builder setDependson(GemValue> dependsOn ) {
this.dependsOn = dependsOn;
return this;
}
public Builder setDefaultvalue(GemValue defaultValue ) {
this.defaultValue = defaultValue;
return this;
}
public Builder setNullvaluecheckstrategy(GemValue nullValueCheckStrategy ) {
this.nullValueCheckStrategy = nullValueCheckStrategy;
return this;
}
public Builder setNullvaluepropertymappingstrategy(GemValue nullValuePropertyMappingStrategy ) {
this.nullValuePropertyMappingStrategy = nullValuePropertyMappingStrategy;
return this;
}
public Builder setMappingcontrol(GemValue mappingControl ) {
this.mappingControl = mappingControl;
return this;
}
public Builder setMirror( AnnotationMirror mirror ) {
this.mirror = mirror;
return this;
}
public MappingGem build() {
return new MappingGem( this );
}
}
}