mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#109 Removing package cycle between model and util
This commit is contained in:
parent
cbccdd847c
commit
c281711aaa
@ -22,7 +22,7 @@ import java.util.Date;
|
||||
|
||||
import org.mapstruct.ap.model.Type;
|
||||
import org.mapstruct.ap.model.TypeConversion;
|
||||
import org.mapstruct.ap.util.TypeFactory;
|
||||
import org.mapstruct.ap.model.TypeFactory;
|
||||
|
||||
/**
|
||||
* Implementations create inline {@link TypeConversion}s such as
|
||||
|
@ -23,10 +23,11 @@ import java.math.BigInteger;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.lang.model.util.Elements;
|
||||
|
||||
import org.mapstruct.ap.model.Type;
|
||||
import org.mapstruct.ap.util.TypeFactory;
|
||||
import org.mapstruct.ap.model.TypeFactory;
|
||||
|
||||
import static org.mapstruct.ap.conversion.ReverseConversion.reverse;
|
||||
|
||||
|
@ -20,7 +20,7 @@ package org.mapstruct.ap.conversion;
|
||||
|
||||
import org.mapstruct.ap.conversion.ConversionProvider.Context;
|
||||
import org.mapstruct.ap.model.Type;
|
||||
import org.mapstruct.ap.util.TypeFactory;
|
||||
import org.mapstruct.ap.model.TypeFactory;
|
||||
|
||||
/**
|
||||
* Default implementation of the {@link Context} passed to conversion providers.
|
||||
|
@ -23,7 +23,6 @@ import java.util.Set;
|
||||
|
||||
import org.mapstruct.ap.util.Collections;
|
||||
import org.mapstruct.ap.util.Strings;
|
||||
import org.mapstruct.ap.util.TypeFactory;
|
||||
|
||||
/**
|
||||
* Mapper reference which is retrieved via the {@code Mappers#getMapper()} method. Used by default if no other component
|
||||
|
@ -29,8 +29,6 @@ import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.util.Elements;
|
||||
|
||||
import org.mapstruct.ap.util.TypeFactory;
|
||||
|
||||
/**
|
||||
* Represents a type implementing a mapper interface (annotated with {@code @Mapper}). This is the root object of the
|
||||
* mapper model.
|
||||
|
@ -21,6 +21,7 @@ package org.mapstruct.ap.model;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.lang.model.element.AnnotationMirror;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.Name;
|
||||
@ -32,8 +33,6 @@ import javax.lang.model.util.Elements;
|
||||
import javax.lang.model.util.SimpleElementVisitor6;
|
||||
import javax.lang.model.util.Types;
|
||||
|
||||
import org.mapstruct.ap.util.TypeFactory;
|
||||
|
||||
/**
|
||||
* Represents the type of a bean property, parameter etc. Each type corresponds to a {@link TypeMirror}, i.e. there are
|
||||
* different instances for e.g. {@code Set<String>} and {@code Set<Integer>}.
|
||||
|
@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.mapstruct.ap.util;
|
||||
package org.mapstruct.ap.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@ -35,7 +35,10 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ConcurrentNavigableMap;
|
||||
import java.util.concurrent.ConcurrentSkipListMap;
|
||||
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import javax.lang.model.type.DeclaredType;
|
||||
import javax.lang.model.type.TypeKind;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
@ -43,7 +46,7 @@ import javax.lang.model.util.Elements;
|
||||
import javax.lang.model.util.Types;
|
||||
|
||||
import org.mapstruct.ap.AnnotationProcessingException;
|
||||
import org.mapstruct.ap.model.Type;
|
||||
import org.mapstruct.ap.MappingTargetPrism;
|
||||
|
||||
/**
|
||||
* Factory creating {@link Type} instances.
|
||||
@ -132,6 +135,45 @@ public class TypeFactory {
|
||||
);
|
||||
}
|
||||
|
||||
public Parameter getSingleParameter(ExecutableElement method) {
|
||||
List<? extends VariableElement> parameters = method.getParameters();
|
||||
|
||||
if ( parameters.size() != 1 ) {
|
||||
//TODO: Log error
|
||||
return null;
|
||||
}
|
||||
|
||||
VariableElement parameter = parameters.get( 0 );
|
||||
|
||||
return new Parameter(
|
||||
parameter.getSimpleName().toString(),
|
||||
getType( parameter.asType() ),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
public List<Parameter> getParameters(ExecutableElement method) {
|
||||
List<? extends VariableElement> parameters = method.getParameters();
|
||||
List<Parameter> result = new ArrayList<Parameter>( parameters.size() );
|
||||
|
||||
for ( VariableElement parameter : parameters ) {
|
||||
result
|
||||
.add(
|
||||
new Parameter(
|
||||
parameter.getSimpleName().toString(),
|
||||
getType( parameter.asType() ),
|
||||
MappingTargetPrism.getInstanceOn( parameter ) != null
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Type getReturnType(ExecutableElement method) {
|
||||
return getType( method.getReturnType() );
|
||||
}
|
||||
|
||||
private List<Type> getTypeParameters(TypeMirror mirror) {
|
||||
if ( mirror.getKind() != TypeKind.DECLARED ) {
|
||||
return java.util.Collections.emptyList();
|
@ -27,8 +27,8 @@ import org.mapstruct.ap.model.Annotation;
|
||||
import org.mapstruct.ap.model.AnnotationMapperReference;
|
||||
import org.mapstruct.ap.model.Mapper;
|
||||
import org.mapstruct.ap.model.MapperReference;
|
||||
import org.mapstruct.ap.model.TypeFactory;
|
||||
import org.mapstruct.ap.option.OptionsHelper;
|
||||
import org.mapstruct.ap.util.TypeFactory;
|
||||
|
||||
/**
|
||||
* An {@link ModelElementProcessor} which converts the given {@link Mapper}
|
||||
|
@ -28,8 +28,8 @@ import javax.lang.model.util.Elements;
|
||||
import javax.lang.model.util.Types;
|
||||
import javax.tools.Diagnostic.Kind;
|
||||
|
||||
import org.mapstruct.ap.model.TypeFactory;
|
||||
import org.mapstruct.ap.option.Options;
|
||||
import org.mapstruct.ap.util.TypeFactory;
|
||||
|
||||
/**
|
||||
* Default implementation of the processor context.
|
||||
|
@ -29,6 +29,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.processing.Messager;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.type.DeclaredType;
|
||||
@ -56,6 +57,7 @@ import org.mapstruct.ap.model.Parameter;
|
||||
import org.mapstruct.ap.model.PropertyMapping;
|
||||
import org.mapstruct.ap.model.Type;
|
||||
import org.mapstruct.ap.model.TypeConversion;
|
||||
import org.mapstruct.ap.model.TypeFactory;
|
||||
import org.mapstruct.ap.model.source.Mapping;
|
||||
import org.mapstruct.ap.model.source.Method;
|
||||
import org.mapstruct.ap.model.source.MethodMatcher;
|
||||
@ -64,7 +66,6 @@ import org.mapstruct.ap.option.ReportingPolicy;
|
||||
import org.mapstruct.ap.util.Executables;
|
||||
import org.mapstruct.ap.util.Filters;
|
||||
import org.mapstruct.ap.util.Strings;
|
||||
import org.mapstruct.ap.util.TypeFactory;
|
||||
|
||||
/**
|
||||
* A {@link ModelElementProcessor} which creates a {@link Mapper} from the given
|
||||
@ -93,7 +94,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Metho
|
||||
|
||||
this.typeFactory = context.getTypeFactory();
|
||||
this.conversions = new Conversions( elementUtils, typeFactory );
|
||||
this.executables = new Executables( typeFactory );
|
||||
this.executables = new Executables();
|
||||
this.filters = new Filters( executables );
|
||||
|
||||
return getMapper( mapperTypeElement, sourceModel );
|
||||
@ -290,7 +291,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Metho
|
||||
elementUtils.getAllMembers( resultTypeElement )
|
||||
);
|
||||
targetAccessors.addAll(
|
||||
filters.alternativeTargetAccessorMethodsIn(
|
||||
alternativeTargetAccessorMethodsIn(
|
||||
elementUtils.getAllMembers( resultTypeElement )
|
||||
)
|
||||
);
|
||||
@ -405,7 +406,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Metho
|
||||
elementUtils.getAllMembers( resultTypeElement )
|
||||
);
|
||||
targetAccessors.addAll(
|
||||
filters.alternativeTargetAccessorMethodsIn(
|
||||
alternativeTargetAccessorMethodsIn(
|
||||
elementUtils.getAllMembers( resultTypeElement )
|
||||
)
|
||||
);
|
||||
@ -487,16 +488,16 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Metho
|
||||
private PropertyMapping getPropertyMapping(List<Method> methods, Method method, Parameter parameter,
|
||||
ExecutableElement sourceAccessor, ExecutableElement targetAcessor,
|
||||
String dateFormat) {
|
||||
Type sourceType = executables.retrieveReturnType( sourceAccessor );
|
||||
Type sourceType = typeFactory.getReturnType( sourceAccessor );
|
||||
Type targetType = null;
|
||||
String conversionString = null;
|
||||
conversionString = parameter.getName() + "." + sourceAccessor.getSimpleName().toString() + "()";
|
||||
|
||||
if ( executables.isSetterMethod( targetAcessor ) ) {
|
||||
targetType = executables.retrieveSingleParameter( targetAcessor ).getType();
|
||||
targetType = typeFactory.getSingleParameter( targetAcessor ).getType();
|
||||
}
|
||||
else if ( executables.isGetterMethod( targetAcessor ) ) {
|
||||
targetType = executables.retrieveReturnType( targetAcessor );
|
||||
targetType = typeFactory.getReturnType( targetAcessor );
|
||||
}
|
||||
|
||||
MappingMethodReference propertyMappingMethod = getMappingMethodReference( methods, sourceType, targetType );
|
||||
@ -786,4 +787,42 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Metho
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* A getter could be an alternative target-accessor if a setter is not available, and the
|
||||
* target is a collection.
|
||||
*
|
||||
* Provided such a getter is initialized lazy by the target class, e.g. in generated JAXB beans.
|
||||
*
|
||||
* @param elements
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private List<ExecutableElement> alternativeTargetAccessorMethodsIn(Iterable<? extends Element> elements) {
|
||||
List<ExecutableElement> setterMethods = filters.setterMethodsIn( elements );
|
||||
List<ExecutableElement> getterMethods = filters.getterMethodsIn( elements );
|
||||
List<ExecutableElement> alternativeTargetAccessorsMethods = new LinkedList<ExecutableElement>();
|
||||
|
||||
if ( getterMethods.size() > setterMethods.size() ) {
|
||||
// there could be a getter method for a list that is not present as setter.
|
||||
// a getter could substitute the setter in that case and act as setter.
|
||||
// (assuming it is initialized)
|
||||
for ( ExecutableElement getterMethod : getterMethods ) {
|
||||
boolean matchFound = false;
|
||||
String getterPropertyName = executables.getPropertyName( getterMethod );
|
||||
for ( ExecutableElement setterMethod : setterMethods ) {
|
||||
String setterPropertyName = executables.getPropertyName( setterMethod );
|
||||
if ( getterPropertyName.equals( setterPropertyName ) ) {
|
||||
matchFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !matchFound && typeFactory.getReturnType( getterMethod ).isCollectionType() ) {
|
||||
alternativeTargetAccessorsMethods.add( getterMethod );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return alternativeTargetAccessorsMethods;
|
||||
}
|
||||
}
|
||||
|
@ -18,10 +18,13 @@
|
||||
*/
|
||||
package org.mapstruct.ap.processor;
|
||||
|
||||
import static javax.lang.model.util.ElementFilter.methodsIn;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.processing.Messager;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.Modifier;
|
||||
@ -39,14 +42,12 @@ import org.mapstruct.ap.MappingPrism;
|
||||
import org.mapstruct.ap.MappingsPrism;
|
||||
import org.mapstruct.ap.model.Parameter;
|
||||
import org.mapstruct.ap.model.Type;
|
||||
import org.mapstruct.ap.model.TypeFactory;
|
||||
import org.mapstruct.ap.model.source.IterableMapping;
|
||||
import org.mapstruct.ap.model.source.MapMapping;
|
||||
import org.mapstruct.ap.model.source.Mapping;
|
||||
import org.mapstruct.ap.model.source.Method;
|
||||
import org.mapstruct.ap.util.Executables;
|
||||
import org.mapstruct.ap.util.TypeFactory;
|
||||
|
||||
import static javax.lang.model.util.ElementFilter.methodsIn;
|
||||
|
||||
/**
|
||||
* A {@link ModelElementProcessor} which retrieves a list of {@link Method}s
|
||||
@ -66,7 +67,7 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
||||
public List<Method> process(ProcessorContext context, TypeElement mapperTypeElement, Void sourceModel) {
|
||||
this.messager = context.getMessager();
|
||||
this.typeFactory = context.getTypeFactory();
|
||||
this.executables = new Executables( typeFactory );
|
||||
this.executables = new Executables();
|
||||
|
||||
return retrieveMethods( mapperTypeElement, true );
|
||||
}
|
||||
@ -119,8 +120,8 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
||||
}
|
||||
|
||||
private Method getMethod(TypeElement element, ExecutableElement method, boolean mapperRequiresImplementation) {
|
||||
List<Parameter> parameters = executables.retrieveParameters( method );
|
||||
Type returnType = executables.retrieveReturnType( method );
|
||||
List<Parameter> parameters = typeFactory.getParameters( method );
|
||||
Type returnType = typeFactory.getReturnType( method );
|
||||
|
||||
//add method with property mappings if an implementation needs to be generated
|
||||
boolean methodRequiresImplementation = method.getModifiers().contains( Modifier.ABSTRACT );
|
||||
|
@ -25,8 +25,8 @@ import javax.lang.model.util.Elements;
|
||||
import javax.lang.model.util.Types;
|
||||
import javax.tools.Diagnostic.Kind;
|
||||
|
||||
import org.mapstruct.ap.model.TypeFactory;
|
||||
import org.mapstruct.ap.option.Options;
|
||||
import org.mapstruct.ap.util.TypeFactory;
|
||||
|
||||
/**
|
||||
* A processor which performs one task of the mapper generation, e.g. retrieving
|
||||
|
@ -19,19 +19,14 @@
|
||||
package org.mapstruct.ap.util;
|
||||
|
||||
import java.beans.Introspector;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.Modifier;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import javax.lang.model.type.TypeKind;
|
||||
|
||||
import org.mapstruct.ap.MappingTargetPrism;
|
||||
import org.mapstruct.ap.model.Parameter;
|
||||
import org.mapstruct.ap.model.Type;
|
||||
|
||||
/**
|
||||
* Provides functionality around {@link ExecutableElement}s.
|
||||
*
|
||||
@ -39,10 +34,7 @@ import org.mapstruct.ap.model.Type;
|
||||
*/
|
||||
public class Executables {
|
||||
|
||||
private final TypeFactory typeFactory;
|
||||
|
||||
public Executables(TypeFactory typeFactory) {
|
||||
this.typeFactory = typeFactory;
|
||||
public Executables() {
|
||||
}
|
||||
|
||||
public boolean isGetterMethod(ExecutableElement method) {
|
||||
@ -111,44 +103,4 @@ public class Executables {
|
||||
|
||||
return propertyNames;
|
||||
}
|
||||
|
||||
public Parameter retrieveSingleParameter(ExecutableElement method) {
|
||||
List<? extends VariableElement> parameters = method.getParameters();
|
||||
|
||||
if ( parameters.size() != 1 ) {
|
||||
//TODO: Log error
|
||||
return null;
|
||||
}
|
||||
|
||||
VariableElement parameter = parameters.get( 0 );
|
||||
|
||||
return new Parameter(
|
||||
parameter.getSimpleName().toString(),
|
||||
typeFactory.getType( parameter.asType() ),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
public List<Parameter> retrieveParameters(ExecutableElement method) {
|
||||
List<? extends VariableElement> parameters = method.getParameters();
|
||||
List<Parameter> result = new ArrayList<Parameter>( parameters.size() );
|
||||
|
||||
for ( VariableElement parameter : parameters ) {
|
||||
result
|
||||
.add(
|
||||
new Parameter(
|
||||
parameter.getSimpleName().toString(),
|
||||
typeFactory.getType( parameter.asType() ),
|
||||
MappingTargetPrism.getInstanceOn( parameter ) != null
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Type retrieveReturnType(ExecutableElement method) {
|
||||
return typeFactory.getType( method.getReturnType() );
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,13 +18,14 @@
|
||||
*/
|
||||
package org.mapstruct.ap.util;
|
||||
|
||||
import static javax.lang.model.util.ElementFilter.methodsIn;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
|
||||
import static javax.lang.model.util.ElementFilter.methodsIn;
|
||||
|
||||
/**
|
||||
* Filter methods for working with {@link Element} collections.
|
||||
*
|
||||
@ -60,42 +61,4 @@ public class Filters {
|
||||
}
|
||||
return setterMethods;
|
||||
}
|
||||
|
||||
/**
|
||||
* A getter could be an alternative target-accessor if a setter is not available, and the
|
||||
* target is a collection.
|
||||
*
|
||||
* Provided such a getter is initialized lazy by the target class, e.g. in generated JAXB beans.
|
||||
*
|
||||
* @param elements
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<ExecutableElement> alternativeTargetAccessorMethodsIn(Iterable<? extends Element> elements) {
|
||||
List<ExecutableElement> setterMethods = setterMethodsIn( elements );
|
||||
List<ExecutableElement> getterMethods = getterMethodsIn( elements );
|
||||
List<ExecutableElement> alternativeTargetAccessorsMethods = new LinkedList<ExecutableElement>();
|
||||
|
||||
if ( getterMethods.size() > setterMethods.size() ) {
|
||||
// there could be a getter method for a list that is not present as setter.
|
||||
// a getter could substitute the setter in that case and act as setter.
|
||||
// (assuming it is initialized)
|
||||
for ( ExecutableElement getterMethod : getterMethods ) {
|
||||
boolean matchFound = false;
|
||||
String getterPropertyName = executables.getPropertyName( getterMethod );
|
||||
for ( ExecutableElement setterMethod : setterMethods ) {
|
||||
String setterPropertyName = executables.getPropertyName( setterMethod );
|
||||
if ( getterPropertyName.equals( setterPropertyName ) ) {
|
||||
matchFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !matchFound && executables.retrieveReturnType( getterMethod ).isCollectionType() ) {
|
||||
alternativeTargetAccessorsMethods.add( getterMethod );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return alternativeTargetAccessorsMethods;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user