diff --git a/core/src/main/java/org/mapstruct/Mapping.java b/core/src/main/java/org/mapstruct/Mapping.java
index 872cba812..1b156f53f 100644
--- a/core/src/main/java/org/mapstruct/Mapping.java
+++ b/core/src/main/java/org/mapstruct/Mapping.java
@@ -35,12 +35,15 @@ import java.util.Date;
public @interface Mapping {
/**
- * The source name of the configured property as defined by the JavaBeans specification. If used to map an enum
- * constant, the name of the constant member is to be given.
+ * The source to use for this Mapping. This can either be:
+ *
+ * - The source name of the configured property as defined by the JavaBeans specification.
+ * - When used to map an enum constant, the name of the constant member is to be given<./li>.
+ *
*
- * @return The source name of the configured property or enum constant
+ * @return The source name of the configured property or enum constant.
*/
- String source();
+ String source() default "";
/**
* The target name of the configured property as defined by the JavaBeans specification. Defaults to the source name
@@ -57,4 +60,12 @@ public @interface Mapping {
* @return A date format string as processable by {@link SimpleDateFormat}.
*/
String dateFormat() default "";
+
+ /**
+ * {@link String} expression that uses available mappings and conversion to set the designated target property to
+ * the provided expression.
+ *
+ * @return expression
+ */
+ String expression() default "";
}
diff --git a/processor/src/main/java/org/mapstruct/ap/model/BeanMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/model/BeanMappingMethod.java
index 65a9ed6e7..83f61f2f3 100644
--- a/processor/src/main/java/org/mapstruct/ap/model/BeanMappingMethod.java
+++ b/processor/src/main/java/org/mapstruct/ap/model/BeanMappingMethod.java
@@ -38,6 +38,10 @@ import org.mapstruct.ap.model.source.SourceMethod;
public class BeanMappingMethod extends MappingMethod {
private final List propertyMappings;
+ private final Map> mappingsByParameter;
+ private final List constantMappings;
+
+
private final FactoryMethod factoryMethod;
public BeanMappingMethod(SourceMethod method,
@@ -45,6 +49,22 @@ public class BeanMappingMethod extends MappingMethod {
FactoryMethod factoryMethod) {
super( method );
this.propertyMappings = propertyMappings;
+
+
+ // intialize constant mappings as all mappings, but take out the ones that can be contributed to a
+ // parameter mapping.
+ this.mappingsByParameter = new HashMap>();
+ this.constantMappings = new ArrayList( propertyMappings );
+ for ( Parameter sourceParameter : getSourceParameters() ) {
+ ArrayList mappingsOfParameter = new ArrayList();
+ mappingsByParameter.put( sourceParameter.getName(), mappingsOfParameter );
+ for ( PropertyMapping mapping : propertyMappings ) {
+ if ( sourceParameter.getName().equals( mapping.getSourceBeanName() ) ) {
+ mappingsOfParameter.add( mapping );
+ constantMappings.remove( mapping );
+ }
+ }
+ }
this.factoryMethod = factoryMethod;
}
@@ -52,18 +72,11 @@ public class BeanMappingMethod extends MappingMethod {
return propertyMappings;
}
- public Map> getPropertyMappingsByParameter() {
- Map> mappingsByParameter = new HashMap>();
+ public List getConstantMappings() {
+ return constantMappings;
+ }
- for ( Parameter sourceParameter : getSourceParameters() ) {
- ArrayList mappingsOfParameter = new ArrayList();
- mappingsByParameter.put( sourceParameter.getName(), mappingsOfParameter );
- for ( PropertyMapping mapping : propertyMappings ) {
- if ( mapping.getSourceBeanName().equals( sourceParameter.getName() ) ) {
- mappingsOfParameter.add( mapping );
- }
- }
- }
+ public Map> getPropertyMappingsByParameter() {
return mappingsByParameter;
}
diff --git a/processor/src/main/java/org/mapstruct/ap/model/source/Mapping.java b/processor/src/main/java/org/mapstruct/ap/model/source/Mapping.java
index 59ae76025..b30ac84af 100644
--- a/processor/src/main/java/org/mapstruct/ap/model/source/Mapping.java
+++ b/processor/src/main/java/org/mapstruct/ap/model/source/Mapping.java
@@ -22,9 +22,11 @@ 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.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
+import javax.tools.Diagnostic;
import org.mapstruct.ap.prism.MappingPrism;
import org.mapstruct.ap.prism.MappingsPrism;
@@ -40,42 +42,63 @@ public class Mapping {
private final String sourceName;
private final String sourceParameterName;
private final String sourcePropertyName;
+ private final String expression;
private final String targetName;
private final String dateFormat;
private final AnnotationMirror mirror;
private final AnnotationValue sourceAnnotationValue;
private final AnnotationValue targetAnnotationValue;
- public static Map> fromMappingsPrism(MappingsPrism mappingsAnnotation, Element element) {
+ public static Map> fromMappingsPrism(MappingsPrism mappingsAnnotation, Element element,
+ Messager messager) {
Map> mappings = new HashMap>();
- for ( MappingPrism mapping : mappingsAnnotation.value() ) {
- if ( !mappings.containsKey( mapping.source() ) ) {
- mappings.put( mapping.source(), new ArrayList() );
+ for ( MappingPrism mappingPrism : mappingsAnnotation.value() ) {
+ if ( !mappings.containsKey( mappingPrism.source() ) ) {
+ mappings.put( mappingPrism.source(), new ArrayList() );
+ }
+ Mapping mapping = fromMappingPrism( mappingPrism, element, messager );
+ if ( mapping != null ) {
+ mappings.get( mappingPrism.source() ).add( mapping );
}
- mappings.get( mapping.source() ).add( fromMappingPrism( mapping, element ) );
}
return mappings;
}
- public static Mapping fromMappingPrism(MappingPrism mapping, Element element) {
+ public static Mapping fromMappingPrism(MappingPrism mappingPrism, Element element, Messager messager) {
String[] sourceNameParts = getSourceNameParts(
- mapping.source(),
+ mappingPrism.source(),
element,
- mapping.mirror,
- mapping.values.source()
+ mappingPrism.mirror,
+ mappingPrism.values.source()
);
+ if ( mappingPrism.source().isEmpty() && mappingPrism.expression().isEmpty() ) {
+ messager.printMessage( Diagnostic.Kind.ERROR,
+ "Either define a source or an expression in a Mapping",
+ element
+ );
+ return null;
+ }
+ else if ( !mappingPrism.source().isEmpty() && !mappingPrism.expression().isEmpty() ) {
+ messager.printMessage( Diagnostic.Kind.ERROR,
+ "Source and expression are both defined in Mapping, either define a source or an expression",
+ element
+ );
+ return null;
+ }
+
return new Mapping(
- mapping.source(),
+ mappingPrism.source(),
sourceNameParts != null ? sourceNameParts[0] : null,
- sourceNameParts != null ? sourceNameParts[1] : mapping.source(),
- mapping.target(),
- mapping.dateFormat(),
- mapping.mirror,
- mapping.values.source(),
- mapping.values.target()
+ sourceNameParts != null ? sourceNameParts[1] : mappingPrism.source(),
+ mappingPrism.expression(),
+ mappingPrism.target(),
+ mappingPrism.dateFormat(),
+ mappingPrism.mirror,
+ mappingPrism.values.source(),
+ mappingPrism.values.target()
);
}
@@ -98,12 +121,13 @@ public class Mapping {
return parts;
}
- private Mapping(String sourceName, String sourceParameterName, String sourcePropertyName, String targetName,
- String dateFormat, AnnotationMirror mirror, AnnotationValue sourceAnnotationValue,
- AnnotationValue targetAnnotationValue) {
+ private Mapping(String sourceName, String sourceParameterName, String sourcePropertyName, String expression,
+ String targetName, String dateFormat, AnnotationMirror mirror,
+ AnnotationValue sourceAnnotationValue, AnnotationValue targetAnnotationValue) {
this.sourceName = sourceName;
this.sourceParameterName = sourceParameterName;
this.sourcePropertyName = sourcePropertyName;
+ this.expression = expression;
this.targetName = targetName.equals( "" ) ? sourceName : targetName;
this.dateFormat = dateFormat;
this.mirror = mirror;
@@ -139,6 +163,11 @@ public class Mapping {
return sourceParameterName;
}
+ public String getExpression() {
+ return expression;
+ }
+
+
public String getTargetName() {
return targetName;
}
@@ -160,16 +189,22 @@ public class Mapping {
}
public Mapping reverse() {
- return new Mapping(
- targetName,
- null,
- targetName,
- sourceName,
- dateFormat,
- mirror,
- sourceAnnotationValue,
- targetAnnotationValue
- );
+ Mapping reverse = null;
+ if ( expression != null ) {
+ /* mapping can only be reversed if the source was not a constant */
+ reverse = new Mapping(
+ targetName,
+ null,
+ targetName,
+ expression,
+ sourceName,
+ dateFormat,
+ mirror,
+ sourceAnnotationValue,
+ targetAnnotationValue
+ );
+ }
+ return reverse;
}
@Override
diff --git a/processor/src/main/java/org/mapstruct/ap/processor/MapperCreationProcessor.java b/processor/src/main/java/org/mapstruct/ap/processor/MapperCreationProcessor.java
index e2b775bc3..6669f058d 100644
--- a/processor/src/main/java/org/mapstruct/ap/processor/MapperCreationProcessor.java
+++ b/processor/src/main/java/org/mapstruct/ap/processor/MapperCreationProcessor.java
@@ -376,7 +376,10 @@ public class MapperCreationProcessor implements ModelElementProcessor() );
}
- reversed.get( mapping.getTargetName() ).add( mapping.reverse() );
+ Mapping reverseMapping = mapping.reverse();
+ if ( reverseMapping != null ) {
+ reversed.get( mapping.getTargetName() ).add( reverseMapping );
+ }
}
}
return reversed;
@@ -387,12 +390,39 @@ public class MapperCreationProcessor implements ModelElementProcessor sourceGetters = parameter.getType().getGetters();
+ // check constants first
+ if ( isSourceConstant ) {
+ return getConstantMapping(
+ mapperReferences,
+ methods,
+ method,
+ sourceConstant,
+ targetAcessor,
+ dateFormat
+ );
+ }
+
+ // then iterate over source accessors (assuming the source is a bean)
for ( ExecutableElement sourceAccessor : sourceGetters ) {
List sourceMappings = method.getMappings().get( sourcePropertyName );
@@ -425,7 +455,6 @@ public class MapperCreationProcessor implements ModelElementProcessor mapperReferences,
+ private PropertyMapping getPropertyMapping(List mapperReferences,
List methods,
SourceMethod method,
Parameter parameter,
@@ -703,6 +730,78 @@ public class MapperCreationProcessor implements ModelElementProcessor mapperReferences,
+ List methods,
+ SourceMethod method,
+ String sourceReference,
+ ExecutableElement targetAcessor,
+ String dateFormat) {
+
+ // source
+ String mappedElement = "constant '" + sourceReference + "'";
+ Type sourceType = typeFactory.getType( String.class );
+
+ // target
+ Type targetType = null;
+ if ( Executables.isSetterMethod( targetAcessor ) ) {
+ targetType = typeFactory.getSingleParameter( targetAcessor ).getType();
+ }
+ else if ( Executables.isGetterMethod( targetAcessor ) ) {
+ targetType = typeFactory.getReturnType( targetAcessor );
+ }
+ String targetPropertyName = Executables.getPropertyName( targetAcessor );
+
+
+ Assignment assignment = mappingResolver.getTargetAssignment(
+ method,
+ mappedElement,
+ mapperReferences,
+ methods,
+ sourceType,
+ targetType,
+ targetPropertyName,
+ dateFormat,
+ sourceReference
+ );
+
+ if ( assignment != null ) {
+
+ // create a new Map or Collection implementation if no method or type conversion
+ if ( targetType != null && ( targetType.isCollectionType() || targetType.isMapType() ) ) {
+ if ( assignment.isSimple() ) {
+ assignment = new NewCollectionOrMapWrapper( assignment );
+ }
+ }
+
+ // target accessor is setter, so decorate assigmment as setter
+ assignment = new SetterWrapper( assignment );
+
+ }
+ else {
+ messager.printMessage(
+ Kind.ERROR,
+ String.format(
+ "Can't map \"%s %s\" to \"%s %s\".",
+ sourceType,
+ sourceReference,
+ targetType,
+ Executables.getPropertyName( targetAcessor )
+ ),
+ method.getExecutable()
+ );
+ }
+ return new PropertyMapping(
+ null,
+ null,
+ null,
+ sourceType,
+ Executables.getPropertyName( targetAcessor ),
+ targetAcessor.getSimpleName().toString(),
+ targetType,
+ assignment
+ );
+ }
+
private IterableMappingMethod getIterableMappingMethod(List mapperReferences,
List methods,
SourceMethod method) {
diff --git a/processor/src/main/java/org/mapstruct/ap/processor/MethodRetrievalProcessor.java b/processor/src/main/java/org/mapstruct/ap/processor/MethodRetrievalProcessor.java
index 06c7eace7..0eaeaec8d 100644
--- a/processor/src/main/java/org/mapstruct/ap/processor/MethodRetrievalProcessor.java
+++ b/processor/src/main/java/org/mapstruct/ap/processor/MethodRetrievalProcessor.java
@@ -384,11 +384,14 @@ public class MethodRetrievalProcessor implements ModelElementProcessor() );
}
- mappings.get( mappingAnnotation.source() ).add( Mapping.fromMappingPrism( mappingAnnotation, method ) );
+ Mapping mapping = Mapping.fromMappingPrism( mappingAnnotation, method, messager );
+ if ( mapping != null ) {
+ mappings.get( mappingAnnotation.source() ).add( mapping );
+ }
}
if ( mappingsAnnotation != null ) {
- mappings.putAll( Mapping.fromMappingsPrism( mappingsAnnotation, method ) );
+ mappings.putAll( Mapping.fromMappingsPrism( mappingsAnnotation, method, messager ) );
}
return mappings;
diff --git a/processor/src/main/resources/org.mapstruct.ap.model.BeanMappingMethod.ftl b/processor/src/main/resources/org.mapstruct.ap.model.BeanMappingMethod.ftl
index 734e75212..54301f3ff 100644
--- a/processor/src/main/resources/org.mapstruct.ap.model.BeanMappingMethod.ftl
+++ b/processor/src/main/resources/org.mapstruct.ap.model.BeanMappingMethod.ftl
@@ -38,6 +38,9 @@
<@includeModel object=propertyMapping targetBeanName=resultName existingInstanceMapping=existingInstanceMapping/>
#list>
#if>
+ <#list constantMappings as constantMapping>
+ <@includeModel object=constantMapping targetBeanName=resultName existingInstanceMapping=existingInstanceMapping/>
+ #list>
<#if returnType.name != "void">
return ${resultName};
diff --git a/processor/src/test/java/org/mapstruct/ap/test/sourceconstants/ErroneousMapper1.java b/processor/src/test/java/org/mapstruct/ap/test/sourceconstants/ErroneousMapper1.java
new file mode 100644
index 000000000..5195124d4
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/sourceconstants/ErroneousMapper1.java
@@ -0,0 +1,43 @@
+/**
+ * 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.
+ */
+package org.mapstruct.ap.test.sourceconstants;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
+
+/**
+ *
+ * @author Sjaak Derksen
+ */
+@Mapper(uses = StringListMapper.class)
+public interface ErroneousMapper1 {
+
+ ErroneousMapper1 INSTANCE = Mappers.getMapper( ErroneousMapper1.class );
+
+ @Mappings( {
+ @Mapping( target = "stringConstant", expression = "stringConstant"),
+ @Mapping( source = "test" , target = "integerConstant", expression = "14"),
+ @Mapping( target = "longWrapperConstant", expression = "3001"),
+ @Mapping( target = "dateConstant", dateFormat = "dd-MM-yyyy", expression = "09-01-2014"),
+ @Mapping( target = "nameConstants", expression = "jack-jill-tom" )
+ } )
+ Target sourceToTarget(Source s);
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/sourceconstants/ErroneousMapper2.java b/processor/src/test/java/org/mapstruct/ap/test/sourceconstants/ErroneousMapper2.java
new file mode 100644
index 000000000..c28837349
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/sourceconstants/ErroneousMapper2.java
@@ -0,0 +1,43 @@
+/**
+ * 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.
+ */
+package org.mapstruct.ap.test.sourceconstants;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
+
+/**
+ *
+ * @author Sjaak Derksen
+ */
+@Mapper(uses = StringListMapper.class)
+public interface ErroneousMapper2 {
+
+ ErroneousMapper2 INSTANCE = Mappers.getMapper( ErroneousMapper2.class );
+
+ @Mappings( {
+ @Mapping( target = "stringConstant", expression = "stringConstant"),
+ @Mapping( target = "integerConstant" ),
+ @Mapping( target = "longWrapperConstant", expression = "3001"),
+ @Mapping( target = "dateConstant", dateFormat = "dd-MM-yyyy", expression = "09-01-2014"),
+ @Mapping( target = "nameConstants", expression = "jack-jill-tom" )
+ } )
+ Target sourceToTarget(Source s);
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/sourceconstants/Source.java b/processor/src/test/java/org/mapstruct/ap/test/sourceconstants/Source.java
new file mode 100644
index 000000000..c5b9f72b7
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/sourceconstants/Source.java
@@ -0,0 +1,39 @@
+/**
+ * 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.
+ */
+package org.mapstruct.ap.test.sourceconstants;
+
+/**
+ *
+ * @author Sjaak Derksen
+ */
+public class Source {
+
+ private String propertyThatShouldBeMapped;
+
+ public String getPropertyThatShouldBeMapped() {
+ return propertyThatShouldBeMapped;
+ }
+
+ public void setPropertyThatShouldBeMapped( String propertyThatShouldBeMapped ) {
+ this.propertyThatShouldBeMapped = propertyThatShouldBeMapped;
+ }
+
+
+
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/sourceconstants/SourceConstantsTest.java b/processor/src/test/java/org/mapstruct/ap/test/sourceconstants/SourceConstantsTest.java
new file mode 100644
index 000000000..42d2dc9ac
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/sourceconstants/SourceConstantsTest.java
@@ -0,0 +1,122 @@
+/**
+ * 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.
+ */
+package org.mapstruct.ap.test.sourceconstants;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Date;
+import javax.tools.Diagnostic.Kind;
+import static org.fest.assertions.Assertions.assertThat;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mapstruct.ap.testutil.IssueKey;
+import org.mapstruct.ap.testutil.WithClasses;
+import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult;
+import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic;
+import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome;
+import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
+
+/**
+ *
+ * @author Sjaak Derksen
+ */
+
+@RunWith(AnnotationProcessorTestRunner.class)
+public class SourceConstantsTest {
+
+ @Test
+ @IssueKey( "187" )
+ @WithClasses( {
+ Source.class,
+ Target.class,
+ SourceTargetMapper.class,
+ StringListMapper.class
+ } )
+ public void shouldMapSameSourcePropertyToSeveralTargetProperties() throws ParseException {
+ Source source = new Source();
+ source.setPropertyThatShouldBeMapped( "SomeProperty" );
+
+ Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source );
+
+ assertThat( target ).isNotNull();
+ assertThat( target.getPropertyThatShouldBeMapped() ).isEqualTo( "SomeProperty" );
+ assertThat( target.getStringConstant() ).isEqualTo( "stringConstant" );
+ assertThat( target.getIntegerConstant() ).isEqualTo( 14 );
+ assertThat( target.getLongWrapperConstant() ).isEqualTo( new Long(3001L) );
+ assertThat( target.getDateConstant() ).isEqualTo( getDate( "dd-MM-yyyy", "09-01-2014") );
+ assertThat( target.getNameConstants() ).isEqualTo( Arrays.asList( "jack", "jill", "tom" ) );
+ }
+
+ @Test
+ @IssueKey( "187" )
+ @WithClasses( {
+ Source.class,
+ Target.class,
+ ErroneousMapper1.class,
+ StringListMapper.class
+ } )
+ @ExpectedCompilationOutcome(
+ value = CompilationResult.FAILED,
+ diagnostics = {
+ @Diagnostic(type = ErroneousMapper1.class,
+ kind = Kind.ERROR,
+ line = 42,
+ messageRegExp = "Source and expression are both defined in Mapping, either define a source or an "
+ + "expression"),
+ @Diagnostic(type = ErroneousMapper1.class,
+ kind = Kind.WARNING,
+ line = 42,
+ messageRegExp = "Unmapped target property: \"integerConstant\"")
+ }
+ )
+ public void errorOnSourceAndExpression() throws ParseException {
+ }
+
+ @Test
+ @IssueKey( "187" )
+ @WithClasses( {
+ Source.class,
+ Target.class,
+ ErroneousMapper2.class,
+ StringListMapper.class
+ } )
+ @ExpectedCompilationOutcome(
+ value = CompilationResult.FAILED,
+ diagnostics = {
+ @Diagnostic(type = ErroneousMapper2.class,
+ kind = Kind.ERROR,
+ line = 42,
+ messageRegExp = "Either define a source or an expression in a Mapping"),
+ @Diagnostic(type = ErroneousMapper2.class,
+ kind = Kind.WARNING,
+ line = 42,
+ messageRegExp = "Unmapped target property: \"integerConstant\"")
+ }
+ )
+ public void errorOnNeitherSourceNorExpression() throws ParseException {
+ }
+
+ private Date getDate(String format, String date) throws ParseException {
+ SimpleDateFormat dateFormat = new SimpleDateFormat( format );
+ Date result = dateFormat.parse( date );
+ return result;
+ }
+
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/sourceconstants/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/sourceconstants/SourceTargetMapper.java
new file mode 100644
index 000000000..095baed10
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/sourceconstants/SourceTargetMapper.java
@@ -0,0 +1,43 @@
+/**
+ * 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.
+ */
+package org.mapstruct.ap.test.sourceconstants;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
+
+/**
+ *
+ * @author Sjaak Derksen
+ */
+@Mapper(uses = StringListMapper.class)
+public interface SourceTargetMapper {
+
+ SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class );
+
+ @Mappings( {
+ @Mapping( target = "stringConstant", expression = "stringConstant"),
+ @Mapping( target = "integerConstant", expression = "14"),
+ @Mapping( target = "longWrapperConstant", expression = "3001"),
+ @Mapping( target = "dateConstant", dateFormat = "dd-MM-yyyy", expression = "09-01-2014"),
+ @Mapping( target = "nameConstants", expression = "jack-jill-tom" )
+ } )
+ Target sourceToTarget(Source s);
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/sourceconstants/StringListMapper.java b/processor/src/test/java/org/mapstruct/ap/test/sourceconstants/StringListMapper.java
new file mode 100644
index 000000000..97d7f3e27
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/sourceconstants/StringListMapper.java
@@ -0,0 +1,30 @@
+/**
+ * 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.
+ */
+package org.mapstruct.ap.test.sourceconstants;
+
+import java.util.Arrays;
+import java.util.List;
+
+
+public class StringListMapper {
+
+ public List stringToStringList(String string) {
+ return string == null ? null : Arrays.asList( string.split( "-" ) );
+ }
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/sourceconstants/Target.java b/processor/src/test/java/org/mapstruct/ap/test/sourceconstants/Target.java
new file mode 100644
index 000000000..37871bd7e
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/sourceconstants/Target.java
@@ -0,0 +1,85 @@
+/**
+ * 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.
+ */
+package org.mapstruct.ap.test.sourceconstants;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ *
+ * @author Sjaak Derksen
+ */
+public class Target {
+
+ private String propertyThatShouldBeMapped;
+ private String stringConstant;
+ private int integerConstant;
+ private Long longWrapperConstant;
+ private Date dateConstant;
+ private List nameConstants;
+
+ public String getPropertyThatShouldBeMapped() {
+ return propertyThatShouldBeMapped;
+ }
+
+ public void setPropertyThatShouldBeMapped( String propertyThatShouldBeMapped ) {
+ this.propertyThatShouldBeMapped = propertyThatShouldBeMapped;
+ }
+
+ public String getStringConstant() {
+ return stringConstant;
+ }
+
+ public void setStringConstant( String stringConstant ) {
+ this.stringConstant = stringConstant;
+ }
+
+ public int getIntegerConstant() {
+ return integerConstant;
+ }
+
+ public void setIntegerConstant( int integerConstant ) {
+ this.integerConstant = integerConstant;
+ }
+
+ public Long getLongWrapperConstant() {
+ return longWrapperConstant;
+ }
+
+ public void setLongWrapperConstant( Long longWrapperConstant ) {
+ this.longWrapperConstant = longWrapperConstant;
+ }
+
+ public Date getDateConstant() {
+ return dateConstant;
+ }
+
+ public void setDateConstant( Date dateConstant ) {
+ this.dateConstant = dateConstant;
+ }
+
+ public List getNameConstants() {
+ return nameConstants;
+ }
+
+ public void setNameConstants( List nameConstants ) {
+ this.nameConstants = nameConstants;
+ }
+
+}