#135 Adding some JavaDocs; Removing unused method

This commit is contained in:
Gunnar Morling 2014-02-26 22:05:17 +01:00
parent 03dca9a8d4
commit 40ed18af0b
12 changed files with 120 additions and 91 deletions

View File

@ -0,0 +1,27 @@
/**
* 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.
*/
/**
* <p>
* Contains "built-in methods" which may be added as private methods to a generated mapper. Built-in methods are an
* alternative to primitive conversions in cases where those don't suffice, e.g. if several lines of code are required
* for a conversion or an exception needs to be handled. Each built-in method has a corresponding template which
* contains the source code of the method.
* </p>
*/
package org.mapstruct.ap.model.source.builtin;

View File

@ -19,6 +19,7 @@
package org.mapstruct.ap.model.source.selector; package org.mapstruct.ap.model.source.selector;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
import org.mapstruct.ap.model.common.Parameter; import org.mapstruct.ap.model.common.Parameter;
@ -33,13 +34,10 @@ import org.mapstruct.ap.model.source.SourceMethod;
*/ */
public class InheritanceSelector implements MethodSelector { public class InheritanceSelector implements MethodSelector {
/**
* {@inheritDoc} {@link MethodSelector}
*/
@Override @Override
public <T extends Method> List<T> getMatchingMethods( public <T extends Method> List<T> getMatchingMethods(
SourceMethod mappingMethod, SourceMethod mappingMethod,
Iterable<T> methods, Collection<T> methods,
Type parameterType, Type parameterType,
Type returnType, Type returnType,
String targetPropertyName String targetPropertyName

View File

@ -18,6 +18,7 @@
*/ */
package org.mapstruct.ap.model.source.selector; package org.mapstruct.ap.model.source.selector;
import java.util.Collection;
import java.util.List; import java.util.List;
import org.mapstruct.ap.model.common.Type; import org.mapstruct.ap.model.common.Type;
@ -25,27 +26,26 @@ import org.mapstruct.ap.model.source.Method;
import org.mapstruct.ap.model.source.SourceMethod; import org.mapstruct.ap.model.source.SourceMethod;
/** /**
* Implementations select those methods from a given input set which match the given source and target type of a mapping
* and optionally other given criteria. An error will be raised if either no or more than one matching method are left
* over after applying all selectors.
*
* @author Sjaak Derksen * @author Sjaak Derksen
*/ */
public interface MethodSelector { public interface MethodSelector {
/** /**
* Selects a method * Selects those methods which match the given types and other criteria
* *
* @param <T> either SourceMethod or BuiltInMethod * @param <T> either SourceMethod or BuiltInMethod
* @param mappingMethod mapping method, defined in Mapper for which this selection is carried out * @param mappingMethod mapping method, defined in Mapper for which this selection is carried out
* @param methods set from available methods * @param methods set of available methods
* @param parameterType parameter type that should be matched * @param parameterType parameter type that should be matched
* @param returnType return type that should be matched * @param returnType return type that should be matched
* @param targetPropertyName some information can be derived from the target property * @param targetPropertyName some information can be derived from the target property
* *
* @return list of methods that passes the matching process * @return list of methods that passes the matching process
*/ */
<T extends Method> List<T> getMatchingMethods( <T extends Method> List<T> getMatchingMethods(SourceMethod mappingMethod, Collection<T> methods, Type parameterType,
SourceMethod mappingMethod, Type returnType, String targetPropertyName);
Iterable<T> methods,
Type parameterType,
Type returnType,
String targetPropertyName
);
} }

View File

@ -19,6 +19,8 @@
package org.mapstruct.ap.model.source.selector; package org.mapstruct.ap.model.source.selector;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List; import java.util.List;
import javax.lang.model.util.Types; import javax.lang.model.util.Types;
@ -27,32 +29,29 @@ import org.mapstruct.ap.model.source.Method;
import org.mapstruct.ap.model.source.SourceMethod; import org.mapstruct.ap.model.source.SourceMethod;
/** /**
* Applies all known {@link MethodSelector}s in order.
*
* @author Sjaak Derksen * @author Sjaak Derksen
*/ */
public class MethodSelectors implements MethodSelector { public class MethodSelectors implements MethodSelector {
private final List<MethodSelector> selectors = new ArrayList<MethodSelector>(); private final List<MethodSelector> selectors;
public MethodSelectors(Types typeUtils) { public MethodSelectors(Types typeUtils) {
selectors =
selectors.add( new InitialSelector() ); Arrays.<MethodSelector>asList(
selectors.add( new InheritanceSelector() ); new TypeSelector(),
selectors.add( new XmlElementDeclSelector( typeUtils ) ); new InheritanceSelector(),
new XmlElementDeclSelector( typeUtils )
);
} }
@Override @Override
public <T extends Method> List<T> getMatchingMethods( public <T extends Method> List<T> getMatchingMethods(SourceMethod mappingMethod, Collection<T> methods,
SourceMethod mappingMethod, Type parameterType, Type returnType,
Iterable<T> methods, String targetPropertyName) {
Type parameterType,
Type returnType,
String targetPropertyName
) {
List<T> candidates = new ArrayList<T>(); List<T> candidates = new ArrayList<T>( methods );
for ( T method : methods ) {
candidates.add( method );
}
for ( MethodSelector selector : selectors ) { for ( MethodSelector selector : selectors ) {
candidates = selector.getMatchingMethods( candidates = selector.getMatchingMethods(
@ -65,5 +64,4 @@ public class MethodSelectors implements MethodSelector {
} }
return candidates; return candidates;
} }
} }

View File

@ -19,30 +19,26 @@
package org.mapstruct.ap.model.source.selector; package org.mapstruct.ap.model.source.selector;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
import org.mapstruct.ap.model.common.Type; import org.mapstruct.ap.model.common.Type;
import org.mapstruct.ap.model.source.Method; import org.mapstruct.ap.model.source.Method;
import org.mapstruct.ap.model.source.MethodMatcher;
import org.mapstruct.ap.model.source.SourceMethod; import org.mapstruct.ap.model.source.SourceMethod;
/** /**
* This class provides the initial set of methods {@link MethodMatcher} * Selects those methods from the given input set which match the given source and target types (via
* {@link MethodMatcher}).
* *
* @author Sjaak Derksen * @author Sjaak Derksen
*/ */
public class InitialSelector implements MethodSelector { public class TypeSelector implements MethodSelector {
/**
* {@inheritDoc} {@link MethodSelector}
*/
@Override @Override
public <T extends Method> List<T> getMatchingMethods( public <T extends Method> List<T> getMatchingMethods(SourceMethod mappingMethod, Collection<T> methods,
SourceMethod mappingMethod, Type parameterType, Type returnType,
Iterable<T> methods, String targetPropertyName) {
Type parameterType,
Type returnType,
String targetPropertyName
) {
List<T> result = new ArrayList<T>(); List<T> result = new ArrayList<T>();
for ( T method : methods ) { for ( T method : methods ) {

View File

@ -19,9 +19,12 @@
package org.mapstruct.ap.model.source.selector; package org.mapstruct.ap.model.source.selector;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
import javax.lang.model.type.TypeMirror; import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Types; import javax.lang.model.util.Types;
import javax.xml.bind.annotation.XmlElementDecl;
import org.mapstruct.ap.model.common.Type; import org.mapstruct.ap.model.common.Type;
import org.mapstruct.ap.model.source.Method; import org.mapstruct.ap.model.source.Method;
@ -29,13 +32,15 @@ import org.mapstruct.ap.model.source.SourceMethod;
import org.mapstruct.ap.prism.XmlElementDeclPrism; import org.mapstruct.ap.prism.XmlElementDeclPrism;
/** /**
* This class matches XmlElmentDecl annotation. Matching happens in the following order. * Selects those methods with matching {@code name} and {@code scope} attributes of the {@link XmlElementDecl}
* 1) Name and Scope matches * annotation, if that is present. Matching happens in the following order:
* 2) Scope matches * <ol>
* 3) Name matches * <li>Name and Scope matches</li>
* 4) No match at all. * <li>Scope matches</li>
* * <li>Name matches</li>
* If there are Name and Scope matches, only those will be returned, otherwise the next in line (scope matches), etc. * </ol>
* If there are name and scope matches, only those will be returned, otherwise the next in line (scope matches), etc. If
* the given method is not annotated with {@code} XmlElementDecl} it will be considered as matching.
* *
* @author Sjaak Derksen * @author Sjaak Derksen
*/ */
@ -47,17 +52,10 @@ public class XmlElementDeclSelector implements MethodSelector {
this.typeUtils = typeUtils; this.typeUtils = typeUtils;
} }
/**
* {@inheritDoc} {@link MethodSelector}
*/
@Override @Override
public <T extends Method> List<T> getMatchingMethods( public <T extends Method> List<T> getMatchingMethods(SourceMethod mappingMethod, Collection<T> methods,
SourceMethod mappingMethod, Type parameterType, Type returnType,
Iterable<T> methods, String targetPropertyName) {
Type parameterType,
Type returnType,
String targetPropertyName
) {
List<T> noXmlDeclMatch = new ArrayList<T>(); List<T> noXmlDeclMatch = new ArrayList<T>();
List<T> nameMatch = new ArrayList<T>(); List<T> nameMatch = new ArrayList<T>();
@ -66,9 +64,9 @@ public class XmlElementDeclSelector implements MethodSelector {
for ( T candidate : methods ) { for ( T candidate : methods ) {
if ( candidate instanceof SourceMethod ) { if ( candidate instanceof SourceMethod ) {
SourceMethod candiateMethod = (SourceMethod) candidate; SourceMethod candidateMethod = (SourceMethod) candidate;
XmlElementDeclPrism xmlElememtDecl XmlElementDeclPrism xmlElememtDecl
= XmlElementDeclPrism.getInstanceOn( candiateMethod.getExecutable() ); = XmlElementDeclPrism.getInstanceOn( candidateMethod.getExecutable() );
if ( xmlElememtDecl != null ) { if ( xmlElememtDecl != null ) {
String name = xmlElememtDecl.name(); String name = xmlElememtDecl.name();
TypeMirror scope = xmlElememtDecl.scope(); TypeMirror scope = xmlElememtDecl.scope();
@ -97,12 +95,12 @@ public class XmlElementDeclSelector implements MethodSelector {
} }
} }
else { else {
// cannot a verdict on xmldeclannotation, so add // cannot make a verdict on xmldeclannotation, so add
noXmlDeclMatch.add( candidate ); noXmlDeclMatch.add( candidate );
} }
} }
else { else {
// cannot a verdict on xmldeclannotation, so add // cannot make a verdict on xmldeclannotation, so add
noXmlDeclMatch.add( candidate ); noXmlDeclMatch.add( candidate );
} }
} }

View File

@ -0,0 +1,25 @@
/**
* 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.
*/
/**
* <p>
* Provides strategies for selecting a matching mapping or factory method when mapping from one attribute to another
* or instantiating the target type of a mapping method, respectively.
* </p>
*/
package org.mapstruct.ap.model.source.selector;

View File

@ -20,12 +20,14 @@ package org.mapstruct.ap.processor;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.annotation.processing.Messager; import javax.annotation.processing.Messager;
import javax.lang.model.element.Element; import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.ExecutableElement;
@ -952,7 +954,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
private <T extends Method> T getBestMatch(SourceMethod mappingMethod, private <T extends Method> T getBestMatch(SourceMethod mappingMethod,
String mappedElement, String mappedElement,
Iterable<T> methods, Collection<T> methods,
Type parameterType, Type parameterType,
Type returnType, Type returnType,
String targetPropertyName) { String targetPropertyName) {
@ -965,7 +967,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
targetPropertyName targetPropertyName
); );
// print a warning if we find more than one method with minimum getParameter type distance // raise an error if more than one mapping method is suitable to map the given source type into the target type
if ( candidates.size() > 1 ) { if ( candidates.size() > 1 ) {
messager.printMessage( messager.printMessage(
@ -987,22 +989,6 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
return null; return null;
} }
private <T extends Method> int addToCandidateListIfMinimal(List<T> candidatesWithBestMathingType,
int bestMatchingTypeDistance, T method,
int currentTypeDistance) {
if ( currentTypeDistance == bestMatchingTypeDistance ) {
candidatesWithBestMathingType.add( method );
}
else if ( currentTypeDistance < bestMatchingTypeDistance ) {
bestMatchingTypeDistance = currentTypeDistance;
candidatesWithBestMathingType.clear();
candidatesWithBestMathingType.add( method );
}
return bestMatchingTypeDistance;
}
private MethodReference getMappingMethodReference(SourceMethod method, List<MapperReference> mapperReferences) { private MethodReference getMappingMethodReference(SourceMethod method, List<MapperReference> mapperReferences) {
MapperReference mapperReference = null; MapperReference mapperReference = null;
for ( MapperReference ref : mapperReferences ) { for ( MapperReference ref : mapperReferences ) {

View File

@ -18,6 +18,10 @@
*/ */
package org.mapstruct.ap.test.jaxb.selection; package org.mapstruct.ap.test.jaxb.selection;
import static org.fest.assertions.Assertions.assertThat;
import javax.xml.bind.annotation.XmlElementDecl;
import org.mapstruct.ap.test.jaxb.selection.test1.OrderType; import org.mapstruct.ap.test.jaxb.selection.test1.OrderType;
import org.mapstruct.ap.test.jaxb.selection.test2.ObjectFactory; import org.mapstruct.ap.test.jaxb.selection.test2.ObjectFactory;
import org.mapstruct.ap.test.jaxb.selection.test2.OrderShippingDetailsType; import org.mapstruct.ap.test.jaxb.selection.test2.OrderShippingDetailsType;
@ -26,22 +30,23 @@ import org.mapstruct.ap.testutil.MapperTestBase;
import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.WithClasses;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import static org.fest.assertions.Assertions.assertThat;
/** /**
* Test for the selection of JAXB mapping and factory methods based on the "name" and "scope" attributes
* of the {@link XmlElementDecl} annotation.
*
* @author Sjaak Derksen * @author Sjaak Derksen
*/ */
@IssueKey("135") @IssueKey("135")
@WithClasses({ @WithClasses({
org.mapstruct.ap.test.jaxb.selection.test1.ObjectFactory.class, ObjectFactory.class, org.mapstruct.ap.test.jaxb.selection.test1.ObjectFactory.class, ObjectFactory.class,
OrderDto.class, OrderShippingDetailsDto.class, OrderType.class, OrderShippingDetailsType.class, OrderDto.class, OrderShippingDetailsDto.class, OrderType.class, OrderShippingDetailsType.class,
SourceTargetMapper.class OrderMapper.class
}) })
public class JaxbFactoryMethodSelectionTest extends MapperTestBase { public class JaxbFactoryMethodSelectionTest extends MapperTestBase {
@Test @Test
public void shouldMatchOnNameAndOrScope() { public void shouldMatchOnNameAndOrScope() {
OrderType target = SourceTargetMapper.INSTANCE.targetToSource( createSource() ); OrderType target = OrderMapper.INSTANCE.targetToSource( createSource() );
// qname and value should match for orderNumbers (distinct 1, 2) // qname and value should match for orderNumbers (distinct 1, 2)
assertThat( target.getOrderNumber1().getValue() ).isEqualTo( 15L ); assertThat( target.getOrderNumber1().getValue() ).isEqualTo( 15L );

View File

@ -50,6 +50,4 @@ public class OrderDto {
public void setShippingDetails(OrderShippingDetailsDto shippingDetails) { public void setShippingDetails(OrderShippingDetailsDto shippingDetails) {
this.shippingDetails = shippingDetails; this.shippingDetails = shippingDetails;
} }
} }

View File

@ -34,9 +34,9 @@ import org.mapstruct.factory.Mappers;
ObjectFactory.class, ObjectFactory.class,
org.mapstruct.ap.test.jaxb.selection.test2.ObjectFactory.class org.mapstruct.ap.test.jaxb.selection.test2.ObjectFactory.class
}) })
public abstract class SourceTargetMapper { public abstract class OrderMapper {
public static final SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); public static final OrderMapper INSTANCE = Mappers.getMapper( OrderMapper.class );
// target 2 source methods // target 2 source methods
public abstract OrderType targetToSource(OrderDto target); public abstract OrderType targetToSource(OrderDto target);

View File

@ -41,6 +41,4 @@ public class OrderShippingDetailsDto {
public void setOrderShippedTo(String orderShippedTo) { public void setOrderShippedTo(String orderShippedTo) {
this.orderShippedTo = orderShippedTo; this.orderShippedTo = orderShippedTo;
} }
} }