mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#365 Moving "spi" package into processor module; Simplifying AccessorNamingStrategy contract
This commit is contained in:
parent
e62b612851
commit
3ba4ded58c
1
pom.xml
1
pom.xml
@ -41,7 +41,6 @@
|
|||||||
<module>core</module>
|
<module>core</module>
|
||||||
<module>core-jdk8</module>
|
<module>core-jdk8</module>
|
||||||
<module>processor</module>
|
<module>processor</module>
|
||||||
<module>spi</module>
|
|
||||||
<module>integrationtest</module>
|
<module>integrationtest</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
|
@ -43,10 +43,6 @@
|
|||||||
<groupId>org.freemarker</groupId>
|
<groupId>org.freemarker</groupId>
|
||||||
<artifactId>freemarker</artifactId>
|
<artifactId>freemarker</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>${project.groupId}</groupId>
|
|
||||||
<artifactId>mapstruct-spi</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Compile-only; Using "provided" scope as there is no such scope in Maven;
|
<!-- Compile-only; Using "provided" scope as there is no such scope in Maven;
|
||||||
these dependencies are not required at runtime, only for prism generation
|
these dependencies are not required at runtime, only for prism generation
|
||||||
|
@ -319,7 +319,7 @@ public class PropertyMapping extends ModelElement {
|
|||||||
// target accessor is setter, so wrap the setter in setter map/ collection handling
|
// target accessor is setter, so wrap the setter in setter map/ collection handling
|
||||||
result = new SetterWrapperForCollectionsAndMaps(
|
result = new SetterWrapperForCollectionsAndMaps(
|
||||||
result,
|
result,
|
||||||
targetWriteAccessor.getSimpleName().toString(),
|
targetWriteAccessor,
|
||||||
newCollectionOrMap
|
newCollectionOrMap
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,11 @@ package org.mapstruct.ap.model.assignment;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.lang.model.element.ExecutableElement;
|
||||||
|
|
||||||
import org.mapstruct.ap.model.common.Type;
|
import org.mapstruct.ap.model.common.Type;
|
||||||
import org.mapstruct.ap.services.Services;
|
import org.mapstruct.ap.services.Services;
|
||||||
|
import org.mapstruct.ap.spi.AccessorNamingStrategy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This wrapper handles the situation were an assignment is done via the setter.
|
* This wrapper handles the situation were an assignment is done via the setter.
|
||||||
@ -42,11 +45,15 @@ public class SetterWrapperForCollectionsAndMaps extends AssignmentWrapper {
|
|||||||
private final Assignment newCollectionOrMapAssignment;
|
private final Assignment newCollectionOrMapAssignment;
|
||||||
|
|
||||||
public SetterWrapperForCollectionsAndMaps(Assignment decoratedAssignment,
|
public SetterWrapperForCollectionsAndMaps(Assignment decoratedAssignment,
|
||||||
String targetSetterName,
|
ExecutableElement targetSetter,
|
||||||
Assignment newCollectionOrMapAssignment) {
|
Assignment newCollectionOrMapAssignment) {
|
||||||
super( decoratedAssignment );
|
super( decoratedAssignment );
|
||||||
this.targetGetterName =
|
|
||||||
Services.getAccessorNamingStrategy().getNonBooleanGetterNameForSetterName( targetSetterName );
|
AccessorNamingStrategy accessorNamingStrategy = Services.getAccessorNamingStrategy();
|
||||||
|
|
||||||
|
this.targetGetterName = accessorNamingStrategy.getCollectionGetterName(
|
||||||
|
accessorNamingStrategy.getPropertyName( targetSetter )
|
||||||
|
);
|
||||||
this.newCollectionOrMapAssignment = newCollectionOrMapAssignment;
|
this.newCollectionOrMapAssignment = newCollectionOrMapAssignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,16 @@ package org.mapstruct.ap.services;
|
|||||||
|
|
||||||
import java.beans.Introspector;
|
import java.beans.Introspector;
|
||||||
|
|
||||||
import org.mapstruct.spi.AccessorNamingStrategy;
|
import javax.lang.model.element.ExecutableElement;
|
||||||
|
import javax.lang.model.element.TypeElement;
|
||||||
|
import javax.lang.model.type.DeclaredType;
|
||||||
|
import javax.lang.model.type.TypeKind;
|
||||||
|
import javax.lang.model.type.TypeMirror;
|
||||||
|
import javax.lang.model.util.SimpleElementVisitor6;
|
||||||
|
import javax.lang.model.util.SimpleTypeVisitor6;
|
||||||
|
|
||||||
|
import org.mapstruct.ap.spi.AccessorNamingStrategy;
|
||||||
|
import org.mapstruct.ap.spi.MethodType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default JavaBeans-compliant implementation of the {@link AccessorNamingStrategy} service provider interface.
|
* The default JavaBeans-compliant implementation of the {@link AccessorNamingStrategy} service provider interface.
|
||||||
@ -30,51 +39,90 @@ import org.mapstruct.spi.AccessorNamingStrategy;
|
|||||||
class DefaultAccessorNamingStrategy implements AccessorNamingStrategy {
|
class DefaultAccessorNamingStrategy implements AccessorNamingStrategy {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDefaultAccessorNamingStrategy(AccessorNamingStrategy defaultAccessorNamingStrategy) {
|
public MethodType getMethodType(ExecutableElement method) {
|
||||||
|
if ( isGetterMethod( method ) ) {
|
||||||
|
return MethodType.GETTER;
|
||||||
|
}
|
||||||
|
else if ( isSetterMethod( method ) ) {
|
||||||
|
return MethodType.SETTER;
|
||||||
|
}
|
||||||
|
else if ( isAdderMethod( method ) ) {
|
||||||
|
return MethodType.ADDER;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return MethodType.OTHER;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private boolean isGetterMethod(ExecutableElement method) {
|
||||||
public boolean isNonBooleanGetterName(String methodName) {
|
String methodName = method.getSimpleName().toString();
|
||||||
return methodName.startsWith( "get" ) && methodName.length() > 3;
|
|
||||||
|
boolean isNonBooleanGetterName = methodName.startsWith( "get" ) && methodName.length() > 3 &&
|
||||||
|
method.getReturnType().getKind() != TypeKind.VOID;
|
||||||
|
|
||||||
|
boolean isBooleanGetterName = methodName.startsWith( "is" ) && methodName.length() > 2;
|
||||||
|
boolean returnTypeIsBoolean = method.getReturnType().getKind() == TypeKind.BOOLEAN ||
|
||||||
|
"java.lang.Boolean".equals( getQualifiedName( method.getReturnType() ) );
|
||||||
|
|
||||||
|
return isNonBooleanGetterName || ( isBooleanGetterName && returnTypeIsBoolean );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public boolean isSetterMethod(ExecutableElement method) {
|
||||||
public boolean isBooleanGetterName(String methodName) {
|
String methodName = method.getSimpleName().toString();
|
||||||
return methodName.startsWith( "is" ) && methodName.length() > 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSetterName(String methodName) {
|
|
||||||
return methodName.startsWith( "set" ) && methodName.length() > 3;
|
return methodName.startsWith( "set" ) && methodName.length() > 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public boolean isAdderMethod(ExecutableElement method) {
|
||||||
public boolean isAdderName(String methodName) {
|
String methodName = method.getSimpleName().toString();
|
||||||
|
|
||||||
return methodName.startsWith( "add" ) && methodName.length() > 3;
|
return methodName.startsWith( "add" ) && methodName.length() > 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPropertyNameForNonBooleanGetterName(String methodName) {
|
public String getPropertyName(ExecutableElement getterOrSetterMethod) {
|
||||||
|
String methodName = getterOrSetterMethod.getSimpleName().toString();
|
||||||
|
return Introspector.decapitalize( methodName.substring( methodName.startsWith( "is" ) ? 2 : 3 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getElementName(ExecutableElement adderMethod) {
|
||||||
|
String methodName = adderMethod.getSimpleName().toString();
|
||||||
return Introspector.decapitalize( methodName.substring( 3 ) );
|
return Introspector.decapitalize( methodName.substring( 3 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPropertyNameForBooleanGetterName(String methodName) {
|
public String getCollectionGetterName(String property) {
|
||||||
return Introspector.decapitalize( methodName.substring( 2 ) );
|
return "get" + property.substring( 0, 1 ).toUpperCase() + property.substring( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private static String getQualifiedName(TypeMirror type) {
|
||||||
public String getPropertyNameForSetterName(String methodName) {
|
DeclaredType declaredType = type.accept(
|
||||||
return Introspector.decapitalize( methodName.substring( 3 ) );
|
new SimpleTypeVisitor6<DeclaredType, Void>() {
|
||||||
|
@Override
|
||||||
|
public DeclaredType visitDeclared(DeclaredType t, Void p) {
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( declaredType == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeElement typeElement = declaredType.asElement().accept(
|
||||||
|
new SimpleElementVisitor6<TypeElement, Void>() {
|
||||||
|
@Override
|
||||||
|
public TypeElement visitType(TypeElement e, Void p) {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
return typeElement != null ? typeElement.getQualifiedName().toString() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getElementNameForAdderName(String methodName) {
|
|
||||||
return Introspector.decapitalize( methodName.substring( 3 ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getNonBooleanGetterNameForSetterName(String methodName) {
|
|
||||||
return "get" + methodName.substring( 3 );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ package org.mapstruct.ap.services;
|
|||||||
|
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
|
|
||||||
import org.mapstruct.spi.AccessorNamingStrategy;
|
import org.mapstruct.ap.spi.AccessorNamingStrategy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple locator for SPI implementations.
|
* A simple locator for SPI implementations.
|
||||||
@ -53,7 +53,7 @@ public class Services {
|
|||||||
if ( impl == null ) {
|
if ( impl == null ) {
|
||||||
impl = defaultImpl;
|
impl = defaultImpl;
|
||||||
}
|
}
|
||||||
impl.setDefaultAccessorNamingStrategy( defaultImpl );
|
|
||||||
return impl;
|
return impl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
* 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.spi;
|
||||||
|
|
||||||
|
import javax.lang.model.element.ExecutableElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A service provider interface for the mapping between method names and properties.
|
||||||
|
*
|
||||||
|
* @author Christian Schuster
|
||||||
|
* @author Gunnar Morling
|
||||||
|
*/
|
||||||
|
public interface AccessorNamingStrategy {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the type of the given method.
|
||||||
|
*/
|
||||||
|
MethodType getMethodType(ExecutableElement method);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the property represented by the given getter or setter method.
|
||||||
|
* <p>
|
||||||
|
* The default implementation will e.g. return "name" for {@code public String getName()} or {@code public void
|
||||||
|
* setName(String name)}.
|
||||||
|
*/
|
||||||
|
String getPropertyName(ExecutableElement getterOrSetterMethod);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the element name of the given adder method.
|
||||||
|
* <p>
|
||||||
|
* The default implementation will e.g. return "item" for {@code public void addItem(String item)}.
|
||||||
|
*/
|
||||||
|
String getElementName(ExecutableElement adderMethod);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the getter name of the given collection property.
|
||||||
|
* <p>
|
||||||
|
* The default implementation will e.g. return "getItems" for "items".
|
||||||
|
*/
|
||||||
|
String getCollectionGetterName(String property);
|
||||||
|
}
|
47
processor/src/main/java/org/mapstruct/ap/spi/MethodType.java
Normal file
47
processor/src/main/java/org/mapstruct/ap/spi/MethodType.java
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/**
|
||||||
|
* 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.spi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Different types of a method.
|
||||||
|
*
|
||||||
|
* @author Gunnar Morling
|
||||||
|
*/
|
||||||
|
public enum MethodType {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A JavaBeans getter method, e.g. {@code public String getName()}.
|
||||||
|
*/
|
||||||
|
GETTER,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A JavaBeans setter method, e.g. {@code public void setName(String name)}.
|
||||||
|
*/
|
||||||
|
SETTER,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An adder method, e.g. {@code public void addItem(String item)}.
|
||||||
|
*/
|
||||||
|
ADDER,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Any method which is neither a JavaBeans getter, setter nor an adder method.
|
||||||
|
*/
|
||||||
|
OTHER;
|
||||||
|
}
|
@ -19,9 +19,7 @@
|
|||||||
package org.mapstruct.ap.util;
|
package org.mapstruct.ap.util;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.lang.model.element.ExecutableElement;
|
import javax.lang.model.element.ExecutableElement;
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
||||||
@ -30,10 +28,10 @@ import javax.lang.model.type.DeclaredType;
|
|||||||
import javax.lang.model.type.TypeKind;
|
import javax.lang.model.type.TypeKind;
|
||||||
import javax.lang.model.type.TypeMirror;
|
import javax.lang.model.type.TypeMirror;
|
||||||
import javax.lang.model.util.Elements;
|
import javax.lang.model.util.Elements;
|
||||||
import javax.lang.model.util.SimpleElementVisitor6;
|
|
||||||
import javax.lang.model.util.SimpleTypeVisitor6;
|
|
||||||
|
|
||||||
import org.mapstruct.ap.services.Services;
|
import org.mapstruct.ap.services.Services;
|
||||||
|
import org.mapstruct.ap.spi.AccessorNamingStrategy;
|
||||||
|
import org.mapstruct.ap.spi.MethodType;
|
||||||
|
|
||||||
import static javax.lang.model.util.ElementFilter.methodsIn;
|
import static javax.lang.model.util.ElementFilter.methodsIn;
|
||||||
import static org.mapstruct.ap.util.SpecificCompilerWorkarounds.replaceTypeElementIfNecessary;
|
import static org.mapstruct.ap.util.SpecificCompilerWorkarounds.replaceTypeElementIfNecessary;
|
||||||
@ -45,38 +43,27 @@ import static org.mapstruct.ap.util.SpecificCompilerWorkarounds.replaceTypeEleme
|
|||||||
*/
|
*/
|
||||||
public class Executables {
|
public class Executables {
|
||||||
|
|
||||||
|
private static AccessorNamingStrategy accessorNamingStrategy = Services.getAccessorNamingStrategy();
|
||||||
|
|
||||||
private Executables() {
|
private Executables() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isGetterMethod(ExecutableElement method) {
|
public static boolean isGetterMethod(ExecutableElement method) {
|
||||||
return isPublic( method ) && ( isNonBooleanGetterMethod( method ) || isBooleanGetterMethod( method ) );
|
return isPublic( method ) &&
|
||||||
}
|
method.getParameters().isEmpty() &&
|
||||||
|
Services.getAccessorNamingStrategy().getMethodType( method ) == MethodType.GETTER;
|
||||||
private static boolean isNonBooleanGetterMethod(ExecutableElement method) {
|
|
||||||
return method.getParameters().isEmpty()
|
|
||||||
&& Services.getAccessorNamingStrategy().isNonBooleanGetterName( method.getSimpleName().toString() )
|
|
||||||
&& method.getReturnType().getKind() != TypeKind.VOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isBooleanGetterMethod(ExecutableElement method) {
|
|
||||||
boolean returnTypeIsBoolean = method.getReturnType().getKind() == TypeKind.BOOLEAN ||
|
|
||||||
"java.lang.Boolean".equals( getQualifiedName( method.getReturnType() ) );
|
|
||||||
|
|
||||||
return method.getParameters().isEmpty()
|
|
||||||
&& Services.getAccessorNamingStrategy().isBooleanGetterName( method.getSimpleName().toString() )
|
|
||||||
&& returnTypeIsBoolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSetterMethod(ExecutableElement method) {
|
public static boolean isSetterMethod(ExecutableElement method) {
|
||||||
return isPublic( method )
|
return isPublic( method )
|
||||||
&& Services.getAccessorNamingStrategy().isSetterName( method.getSimpleName().toString() )
|
&& method.getParameters().size() == 1
|
||||||
&& method.getParameters().size() == 1;
|
&& accessorNamingStrategy.getMethodType( method ) == MethodType.SETTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isAdderMethod(ExecutableElement method) {
|
public static boolean isAdderMethod(ExecutableElement method) {
|
||||||
return isPublic( method )
|
return isPublic( method )
|
||||||
&& Services.getAccessorNamingStrategy().isAdderName( method.getSimpleName().toString() )
|
&& method.getParameters().size() == 1
|
||||||
&& method.getParameters().size() == 1;
|
&& accessorNamingStrategy.getMethodType( method ) == MethodType.ADDER;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isPublic(ExecutableElement method) {
|
private static boolean isPublic(ExecutableElement method) {
|
||||||
@ -84,23 +71,7 @@ public class Executables {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String getPropertyName(ExecutableElement getterOrSetterMethod) {
|
public static String getPropertyName(ExecutableElement getterOrSetterMethod) {
|
||||||
if ( isNonBooleanGetterMethod( getterOrSetterMethod ) ) {
|
return accessorNamingStrategy.getPropertyName( getterOrSetterMethod );
|
||||||
return Services.getAccessorNamingStrategy().getPropertyNameForNonBooleanGetterName(
|
|
||||||
getterOrSetterMethod.getSimpleName().toString()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if ( isBooleanGetterMethod( getterOrSetterMethod ) ) {
|
|
||||||
return Services.getAccessorNamingStrategy().getPropertyNameForBooleanGetterName(
|
|
||||||
getterOrSetterMethod.getSimpleName().toString()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if ( isSetterMethod( getterOrSetterMethod ) ) {
|
|
||||||
return Services.getAccessorNamingStrategy().getPropertyNameForSetterName(
|
|
||||||
getterOrSetterMethod.getSimpleName().toString()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalArgumentException( "Executable " + getterOrSetterMethod + " is not getter or setter method." );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -109,51 +80,7 @@ public class Executables {
|
|||||||
* {@code addChild(Child v)}, the element name would be 'Child'.
|
* {@code addChild(Child v)}, the element name would be 'Child'.
|
||||||
*/
|
*/
|
||||||
public static String getElementNameForAdder(ExecutableElement adderMethod) {
|
public static String getElementNameForAdder(ExecutableElement adderMethod) {
|
||||||
if ( isAdderMethod( adderMethod ) ) {
|
return accessorNamingStrategy.getElementName( adderMethod );
|
||||||
return Services.getAccessorNamingStrategy().getElementNameForAdderName(
|
|
||||||
adderMethod.getSimpleName().toString()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalArgumentException( "Executable " + adderMethod + " is not an adder method." );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Set<String> getPropertyNames(List<ExecutableElement> propertyAccessors) {
|
|
||||||
Set<String> propertyNames = new HashSet<String>();
|
|
||||||
|
|
||||||
for ( ExecutableElement executableElement : propertyAccessors ) {
|
|
||||||
propertyNames.add( getPropertyName( executableElement ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
return propertyNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String getQualifiedName(TypeMirror type) {
|
|
||||||
DeclaredType declaredType = type.accept(
|
|
||||||
new SimpleTypeVisitor6<DeclaredType, Void>() {
|
|
||||||
@Override
|
|
||||||
public DeclaredType visitDeclared(DeclaredType t, Void p) {
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
null
|
|
||||||
);
|
|
||||||
|
|
||||||
if ( declaredType == null ) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeElement typeElement = declaredType.asElement().accept(
|
|
||||||
new SimpleElementVisitor6<TypeElement, Void>() {
|
|
||||||
@Override
|
|
||||||
public TypeElement visitType(TypeElement e, Void p) {
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
null
|
|
||||||
);
|
|
||||||
|
|
||||||
return typeElement != null ? typeElement.getQualifiedName().toString() : null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -196,7 +123,8 @@ public class Executables {
|
|||||||
elementUtils,
|
elementUtils,
|
||||||
alreadyAdded,
|
alreadyAdded,
|
||||||
asTypeElement( element.getSuperclass() ),
|
asTypeElement( element.getSuperclass() ),
|
||||||
parentType );
|
parentType
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( TypeMirror interfaceType : element.getInterfaces() ) {
|
for ( TypeMirror interfaceType : element.getInterfaces() ) {
|
||||||
@ -204,7 +132,8 @@ public class Executables {
|
|||||||
elementUtils,
|
elementUtils,
|
||||||
alreadyAdded,
|
alreadyAdded,
|
||||||
asTypeElement( interfaceType ),
|
asTypeElement( interfaceType ),
|
||||||
parentType );
|
parentType
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -220,7 +149,7 @@ public class Executables {
|
|||||||
List<ExecutableElement> safeToAdd = new ArrayList<ExecutableElement>( methodsToAdd.size() );
|
List<ExecutableElement> safeToAdd = new ArrayList<ExecutableElement>( methodsToAdd.size() );
|
||||||
for ( ExecutableElement toAdd : methodsToAdd ) {
|
for ( ExecutableElement toAdd : methodsToAdd ) {
|
||||||
if ( isNotObjectEquals( toAdd )
|
if ( isNotObjectEquals( toAdd )
|
||||||
&& wasNotYetOverridden( elementUtils, alreadyCollected, toAdd, parentType ) ) {
|
&& wasNotYetOverridden( elementUtils, alreadyCollected, toAdd, parentType ) ) {
|
||||||
safeToAdd.add( toAdd );
|
safeToAdd.add( toAdd );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -246,10 +175,11 @@ public class Executables {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param elementUtils the elementUtils
|
* @param elementUtils the elementUtils
|
||||||
* @param alreadyAdded the list of already collected methods of one type hierarchy (order is from sub-types to
|
* @param methods the list of already collected methods of one type hierarchy (order is from sub-types to
|
||||||
* super-types)
|
* super-types)
|
||||||
* @param executable the method to check
|
* @param executable the method to check
|
||||||
* @param parentType the type for which elements are collected
|
* @param parentType the type for which elements are collected
|
||||||
|
*
|
||||||
* @return {@code true}, iff the given executable was not yet overridden by a method in the given list.
|
* @return {@code true}, iff the given executable was not yet overridden by a method in the given list.
|
||||||
*/
|
*/
|
||||||
private static boolean wasNotYetOverridden(Elements elementUtils, List<ExecutableElement> alreadyAdded,
|
private static boolean wasNotYetOverridden(Elements elementUtils, List<ExecutableElement> alreadyAdded,
|
||||||
|
68
spi/pom.xml
68
spi/pom.xml
@ -1,68 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!--
|
|
||||||
|
|
||||||
Copyright 2012-2014 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.
|
|
||||||
|
|
||||||
-->
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<groupId>org.mapstruct</groupId>
|
|
||||||
<artifactId>mapstruct-parent</artifactId>
|
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
|
||||||
<relativePath>../parent/pom.xml</relativePath>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<artifactId>mapstruct-spi</artifactId>
|
|
||||||
<packaging>jar</packaging>
|
|
||||||
<name>MapStruct Service Provider Interfaces</name>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<!-- Test -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>junit</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.easytesting</groupId>
|
|
||||||
<artifactId>fest-assert</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>check-style</id>
|
|
||||||
<phase>verify</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>checkstyle</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
</project>
|
|
@ -1,134 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.spi;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A service provider interface for the mapping between method names and properties.
|
|
||||||
*
|
|
||||||
* @author Christian Schuster
|
|
||||||
*/
|
|
||||||
public interface AccessorNamingStrategy {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the default {@link AccessorNamingStrategy} implementation. Custom implementations may use it to
|
|
||||||
* keep parts of the default behavior. This method is invoked before any other method of the interface.
|
|
||||||
* <p>
|
|
||||||
* Default implementation: Does nothing.
|
|
||||||
*
|
|
||||||
* @param defaultAccessorNamingStrategy The default implementation.
|
|
||||||
*/
|
|
||||||
void setDefaultAccessorNamingStrategy(AccessorNamingStrategy defaultAccessorNamingStrategy);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if a method name defines a getter with a non-boolean return type.
|
|
||||||
* <p>
|
|
||||||
* Default implementation: Method name starts with "get" and is longer than 3 characters.
|
|
||||||
*
|
|
||||||
* @param methodName The method name.
|
|
||||||
* @return {@code true} if the method name can be a non-boolean getter, {@code false} otherwise.
|
|
||||||
*/
|
|
||||||
boolean isNonBooleanGetterName(String methodName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if a method name defines a getter with a boolean return type.
|
|
||||||
* <p>
|
|
||||||
* Default implementation: Method name starts with "is" and is longer than 2 characters.
|
|
||||||
*
|
|
||||||
* @param methodName The method name.
|
|
||||||
* @return {@code true} if the method name can be a boolean getter, {@code false} otherwise.
|
|
||||||
*/
|
|
||||||
boolean isBooleanGetterName(String methodName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if a method name defines a setter.
|
|
||||||
* <p>
|
|
||||||
* Default implementation: Method name starts with "set" and is longer than 3 characters.
|
|
||||||
*
|
|
||||||
* @param methodName The method name.
|
|
||||||
* @return {@code true} if the method name can be a setter, {@code false} otherwise.
|
|
||||||
*/
|
|
||||||
boolean isSetterName(String methodName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if a method name defines an adder.
|
|
||||||
* <p>
|
|
||||||
* Default implementation: Method name starts with "add" and is longer than 3 characters.
|
|
||||||
*
|
|
||||||
* @param methodName The method name.
|
|
||||||
* @return {@code true} if the method name can be an adder, {@code false} otherwise.
|
|
||||||
*/
|
|
||||||
boolean isAdderName(String methodName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extract the property name from a method name for which {@link #isNonBooleanGetterName(String)} returned
|
|
||||||
* {@code true}.
|
|
||||||
* <p>
|
|
||||||
* Default implementation: Remove first 3 characters ("get") of the method name, and
|
|
||||||
* {@link java.beans.Introspector#decapitalize(String) decapitalize} the result.
|
|
||||||
*
|
|
||||||
* @param methodName The method name, guaranteed to be a non-boolean getter name.
|
|
||||||
* @return The property name corresponding to the method name.
|
|
||||||
*/
|
|
||||||
String getPropertyNameForNonBooleanGetterName(String methodName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extract the property name from a method name for which {@link #isBooleanGetterName(String)} returned
|
|
||||||
* {@code true}.
|
|
||||||
* <p>
|
|
||||||
* Default implementation: Remove the first 2 characters ("is") of the method name, and
|
|
||||||
* {@link java.beans.Introspector#decapitalize(String) decapitalize} the result.
|
|
||||||
*
|
|
||||||
* @param methodName The method name, guaranteed to be a boolean getter name.
|
|
||||||
* @return The property name corresponding to the method name.
|
|
||||||
*/
|
|
||||||
String getPropertyNameForBooleanGetterName(String methodName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extract the property name from a method name for which {@link #isSetterName(String)} returned {@code true}.
|
|
||||||
* <p>
|
|
||||||
* Default implementation: Remove the first 3 characters ("set") of the method name, and
|
|
||||||
* {@link java.beans.Introspector#decapitalize(String) decapitalize} the result.
|
|
||||||
*
|
|
||||||
* @param methodName The method name, guaranteed to be a setter name.
|
|
||||||
* @return The property name corresponding to the method name.
|
|
||||||
*/
|
|
||||||
String getPropertyNameForSetterName(String methodName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extract the element name (singular form of the collection's property name) from a method name for which
|
|
||||||
* {@link #isAdderName(String)} returned {@code true}.
|
|
||||||
* <p>
|
|
||||||
* Default implementation: Remove the first 3 characters ("add") of the method name, and
|
|
||||||
* {@link java.beans.Introspector#decapitalize(String) decapitalize} the result.
|
|
||||||
*
|
|
||||||
* @param methodName The method name, guaranteed to be an adder name.
|
|
||||||
* @return The element name corresponding to the method name.
|
|
||||||
*/
|
|
||||||
String getElementNameForAdderName(String methodName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extract the non-boolean getter method name from the setter method name of the same property.
|
|
||||||
* <p>
|
|
||||||
* Default implementation: Replace the first 3 characters ("get") of the method name with "set".
|
|
||||||
*
|
|
||||||
* @param methodName The method name, guaranteed to be a setter name.
|
|
||||||
* @return The corresponding non-boolean getter method name.
|
|
||||||
*/
|
|
||||||
String getNonBooleanGetterNameForSetterName(String methodName);
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user