#58 Registering several more implementation types for collection types

This commit is contained in:
Gunnar Morling 2013-07-21 23:41:38 +02:00
parent 45968f9fd7
commit 764f5040da
4 changed files with 74 additions and 8 deletions

View File

@ -65,8 +65,13 @@ public class MapMappingMethod extends MappingMethod {
@Override
public Set<Type> getImportTypes() {
Set<Type> types = super.getImportTypes();
if ( valueConversion != null ) {
types.addAll( valueConversion.getImportTypes() );
}
if ( keyConversion != null ) {
types.addAll( keyConversion.getImportTypes() );
}
return types;
}

View File

@ -26,9 +26,17 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.NavigableMap;
import java.util.NavigableSet;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentNavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;
import org.mapstruct.ap.util.Strings;
@ -55,20 +63,32 @@ public class Type extends AbstractModelElement implements Comparable<Type> {
new ConcurrentHashMap<String, Type>();
static {
DEFAULT_COLLECTION_IMPLEMENTATION_TYPES.put( List.class.getName(), forClass( ArrayList.class ) );
DEFAULT_COLLECTION_IMPLEMENTATION_TYPES.put( Set.class.getName(), forClass( HashSet.class ) );
DEFAULT_ITERABLE_IMPLEMENTATION_TYPES.put( Iterable.class.getName(), forClass( ArrayList.class ) );
DEFAULT_COLLECTION_IMPLEMENTATION_TYPES.put( Collection.class.getName(), forClass( ArrayList.class ) );
DEFAULT_ITERABLE_IMPLEMENTATION_TYPES.put( Iterable.class.getName(), forClass( ArrayList.class ) );
DEFAULT_COLLECTION_IMPLEMENTATION_TYPES.put( List.class.getName(), forClass( ArrayList.class ) );
DEFAULT_COLLECTION_IMPLEMENTATION_TYPES.put( Set.class.getName(), forClass( HashSet.class ) );
DEFAULT_COLLECTION_IMPLEMENTATION_TYPES.put( SortedSet.class.getName(), forClass( TreeSet.class ) );
DEFAULT_COLLECTION_IMPLEMENTATION_TYPES.put( NavigableSet.class.getName(), forClass( TreeSet.class ) );
DEFAULT_ITERABLE_IMPLEMENTATION_TYPES.putAll( DEFAULT_COLLECTION_IMPLEMENTATION_TYPES );
DEFAULT_MAP_IMPLEMENTATION_TYPES.put( Map.class.getName(), forClass( HashMap.class ) );
DEFAULT_MAP_IMPLEMENTATION_TYPES.put( SortedMap.class.getName(), forClass( TreeMap.class ) );
DEFAULT_MAP_IMPLEMENTATION_TYPES.put( NavigableMap.class.getName(), forClass( TreeMap.class ) );
DEFAULT_MAP_IMPLEMENTATION_TYPES.put( ConcurrentMap.class.getName(), forClass( ConcurrentHashMap.class ) );
DEFAULT_MAP_IMPLEMENTATION_TYPES.put(
ConcurrentNavigableMap.class.getName(),
forClass( ConcurrentSkipListMap.class )
);
}
private final String canonicalName;
private final String packageName;
private final String name;
private final List<Type> typeParameters;
private final boolean isInterface;
private final boolean isEnumType;
private final boolean isCollectionType;
private final boolean isIterableType;
@ -85,6 +105,7 @@ public class Type extends AbstractModelElement implements Comparable<Type> {
clazz.getCanonicalName(),
pakkage.getName(),
clazz.getSimpleName(),
clazz.isInterface(),
clazz.isEnum(),
Collection.class.isAssignableFrom( clazz ),
Iterable.class.isAssignableFrom( clazz ),
@ -98,18 +119,30 @@ public class Type extends AbstractModelElement implements Comparable<Type> {
}
public Type(String name) {
this( name, null, name, false, false, false, false, Collections.<Type>emptyList() );
this( name, null, name, false, false, false, false, false, Collections.<Type>emptyList() );
}
public Type(String packageName, String name) {
this( packageName + "." + name, packageName, name, false, false, false, false, Collections.<Type>emptyList() );
this(
packageName + "." + name,
packageName,
name,
false,
false,
false,
false,
false,
Collections.<Type>emptyList()
);
}
public Type(String canonicalName, String packageName, String name, boolean isEnumType, boolean isCollectionType,
public Type(String canonicalName, String packageName, String name, boolean isInterface, boolean isEnumType,
boolean isCollectionType,
boolean isIterableType, boolean isMapType, List<Type> typeParameters) {
this.canonicalName = canonicalName;
this.packageName = packageName;
this.name = name;
this.isInterface = isInterface;
this.isEnumType = isEnumType;
this.isCollectionType = isCollectionType;
this.isIterableType = isIterableType;
@ -136,6 +169,7 @@ public class Type extends AbstractModelElement implements Comparable<Type> {
mapType.getPackageName() + "." + mapType.getName(),
mapType.getPackageName(),
mapType.getName(),
mapType.isInterface(),
mapType.isEnumType(),
mapType.isCollectionType(),
mapType.isIterableType(),
@ -168,6 +202,10 @@ public class Type extends AbstractModelElement implements Comparable<Type> {
return packageName == null && PRIMITIVE_TYPE_NAMES.contains( name );
}
public boolean isInterface() {
return isInterface;
}
public boolean isEnumType() {
return isEnumType;
}
@ -188,6 +226,12 @@ public class Type extends AbstractModelElement implements Comparable<Type> {
return isCollectionType;
}
public Type getImplementationType() {
return collectionImplementationType != null ? collectionImplementationType :
iterableImplementationType != null ? iterableImplementationType :
mapImplementationType;
}
public boolean isIterableType() {
return isIterableType;
}

View File

@ -157,6 +157,8 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Metho
continue;
}
reportErrorIfNoImplementationTypeIsRegisteredForInterfaceReturnType( method );
Method reverseMappingMethod = getReverseMappingMethod( methods, method );
if ( method.isIterableMapping() ) {
@ -185,6 +187,20 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Metho
return mappingMethods;
}
private void reportErrorIfNoImplementationTypeIsRegisteredForInterfaceReturnType(Method method) {
if ( method.getReturnType() != Type.VOID && method.getReturnType().isInterface() &&
method.getReturnType().getImplementationType() == null ) {
messager.printMessage(
Kind.ERROR,
String.format(
"No implementation type is registered for return type %s.",
method.getReturnType()
),
method.getExecutable()
);
}
}
private Map<String, Mapping> reverse(Map<String, Mapping> mappings) {
Map<String, Mapping> reversed = new HashMap<String, Mapping>();

View File

@ -60,6 +60,7 @@ public class TypeUtil {
( (TypeElement) type.asElement() ).getQualifiedName().toString(),
elementUtils.getPackageOf( type.asElement() ).toString(),
type.asElement().getSimpleName().toString(),
type.asElement().getKind() == ElementKind.INTERFACE,
type.asElement().getKind() == ElementKind.ENUM,
isCollectionType( type ),
isIterableType,