#424 Add Compiler implementation info to @Generated#comment

This commit is contained in:
Andreas Gudian 2015-01-23 21:40:56 +01:00
parent 8a449e12fd
commit bd89a054e8
14 changed files with 444 additions and 51 deletions

View File

@ -83,6 +83,7 @@ import org.mapstruct.ap.util.AnnotationProcessingException;
@SupportedAnnotationTypes("org.mapstruct.Mapper") @SupportedAnnotationTypes("org.mapstruct.Mapper")
@SupportedOptions({ @SupportedOptions({
MappingProcessor.SUPPRESS_GENERATOR_TIMESTAMP, MappingProcessor.SUPPRESS_GENERATOR_TIMESTAMP,
MappingProcessor.SUPPRESS_GENERATOR_VERSION_INFO_COMMENT,
MappingProcessor.UNMAPPED_TARGET_POLICY, MappingProcessor.UNMAPPED_TARGET_POLICY,
MappingProcessor.DEFAULT_COMPONENT_MODEL MappingProcessor.DEFAULT_COMPONENT_MODEL
}) })
@ -94,6 +95,8 @@ public class MappingProcessor extends AbstractProcessor {
private static final boolean ANNOTATIONS_CLAIMED_EXCLUSIVELY = false; private static final boolean ANNOTATIONS_CLAIMED_EXCLUSIVELY = false;
protected static final String SUPPRESS_GENERATOR_TIMESTAMP = "mapstruct.suppressGeneratorTimestamp"; protected static final String SUPPRESS_GENERATOR_TIMESTAMP = "mapstruct.suppressGeneratorTimestamp";
protected static final String SUPPRESS_GENERATOR_VERSION_INFO_COMMENT =
"mapstruct.suppressGeneratorVersionInfoComment";
protected static final String UNMAPPED_TARGET_POLICY = "mapstruct.unmappedTargetPolicy"; protected static final String UNMAPPED_TARGET_POLICY = "mapstruct.unmappedTargetPolicy";
protected static final String DEFAULT_COMPONENT_MODEL = "mapstruct.defaultComponentModel"; protected static final String DEFAULT_COMPONENT_MODEL = "mapstruct.defaultComponentModel";
@ -111,6 +114,7 @@ public class MappingProcessor extends AbstractProcessor {
return new Options( return new Options(
Boolean.valueOf( processingEnv.getOptions().get( SUPPRESS_GENERATOR_TIMESTAMP ) ), Boolean.valueOf( processingEnv.getOptions().get( SUPPRESS_GENERATOR_TIMESTAMP ) ),
Boolean.valueOf( processingEnv.getOptions().get( SUPPRESS_GENERATOR_VERSION_INFO_COMMENT ) ),
unmappedTargetPolicy != null ? ReportingPolicy.valueOf( unmappedTargetPolicy ) : null, unmappedTargetPolicy != null ? ReportingPolicy.valueOf( unmappedTargetPolicy ) : null,
processingEnv.getOptions().get( DEFAULT_COMPONENT_MODEL ) processingEnv.getOptions().get( DEFAULT_COMPONENT_MODEL )
); );

View File

@ -21,14 +21,18 @@ package org.mapstruct.ap.model;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.TreeSet; import java.util.TreeSet;
import javax.lang.model.element.ElementKind; import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements; import javax.lang.model.util.Elements;
import org.mapstruct.ap.model.common.Accessibility; import org.mapstruct.ap.model.common.Accessibility;
import org.mapstruct.ap.model.common.ModelElement; import org.mapstruct.ap.model.common.ModelElement;
import org.mapstruct.ap.model.common.Type; import org.mapstruct.ap.model.common.Type;
import org.mapstruct.ap.model.common.TypeFactory; import org.mapstruct.ap.model.common.TypeFactory;
import org.mapstruct.ap.option.Options;
import org.mapstruct.ap.prism.DecoratedWithPrism; import org.mapstruct.ap.prism.DecoratedWithPrism;
import org.mapstruct.ap.version.VersionInformation;
/** /**
* Represents a decorator applied to a generated mapper type. * Represents a decorator applied to a generated mapper type.
@ -41,7 +45,7 @@ public class Decorator extends GeneratedType {
private Decorator(TypeFactory typeFactory, String packageName, String name, String superClassName, private Decorator(TypeFactory typeFactory, String packageName, String name, String superClassName,
String interfaceName, List<MappingMethod> methods, List<? extends ModelElement> fields, String interfaceName, List<MappingMethod> methods, List<? extends ModelElement> fields,
boolean suppressGeneratorTimestamp, Accessibility accessibility ) { Options options, VersionInformation versionInformation, Accessibility accessibility) {
super( super(
typeFactory, typeFactory,
packageName, packageName,
@ -50,7 +54,8 @@ public class Decorator extends GeneratedType {
interfaceName, interfaceName,
methods, methods,
fields, fields,
suppressGeneratorTimestamp, options,
versionInformation,
accessibility, accessibility,
new TreeSet<Type>() new TreeSet<Type>()
); );
@ -58,8 +63,8 @@ public class Decorator extends GeneratedType {
public static Decorator getInstance(Elements elementUtils, TypeFactory typeFactory, TypeElement mapperElement, public static Decorator getInstance(Elements elementUtils, TypeFactory typeFactory, TypeElement mapperElement,
DecoratedWithPrism decoratorPrism, List<MappingMethod> methods, DecoratedWithPrism decoratorPrism, List<MappingMethod> methods,
boolean hasDelegateConstructor, boolean hasDelegateConstructor, Options options,
boolean suppressGeneratorTimestamp) { VersionInformation versionInformation) {
Type decoratorType = typeFactory.getType( decoratorPrism.value() ); Type decoratorType = typeFactory.getType( decoratorPrism.value() );
return new Decorator( return new Decorator(
@ -77,7 +82,8 @@ public class Decorator extends GeneratedType {
hasDelegateConstructor hasDelegateConstructor
) )
), ),
suppressGeneratorTimestamp, options,
versionInformation,
Accessibility.fromModifiers( mapperElement.getModifiers() ) Accessibility.fromModifiers( mapperElement.getModifiers() )
); );
} }

View File

@ -18,21 +18,20 @@
*/ */
package org.mapstruct.ap.model; package org.mapstruct.ap.model;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Enumeration;
import java.util.List; import java.util.List;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.jar.Manifest;
import javax.annotation.Generated; import javax.annotation.Generated;
import org.mapstruct.ap.model.common.Accessibility; import org.mapstruct.ap.model.common.Accessibility;
import org.mapstruct.ap.model.common.ModelElement; import org.mapstruct.ap.model.common.ModelElement;
import org.mapstruct.ap.model.common.Type; import org.mapstruct.ap.model.common.Type;
import org.mapstruct.ap.model.common.TypeFactory; import org.mapstruct.ap.model.common.TypeFactory;
import org.mapstruct.ap.option.Options;
import org.mapstruct.ap.version.VersionInformation;
/** /**
* A type generated by MapStruct, e.g. representing a mapper type. * A type generated by MapStruct, e.g. representing a mapper type.
@ -41,9 +40,6 @@ import org.mapstruct.ap.model.common.TypeFactory;
*/ */
public abstract class GeneratedType extends ModelElement { public abstract class GeneratedType extends ModelElement {
private static final String COMMENT_TAG = "Implementation-Version";
private static final String COMMENTS = initComment();
private final String packageName; private final String packageName;
private final String name; private final String name;
private final String superClassName; private final String superClassName;
@ -55,6 +51,8 @@ public abstract class GeneratedType extends ModelElement {
private final SortedSet<Type> extraImportedTypes; private final SortedSet<Type> extraImportedTypes;
private final boolean suppressGeneratorTimestamp; private final boolean suppressGeneratorTimestamp;
private final boolean suppressGeneratorVersionComment;
private final VersionInformation versionInformation;
private final Accessibility accessibility; private final Accessibility accessibility;
/** /**
@ -62,11 +60,13 @@ public abstract class GeneratedType extends ModelElement {
*/ */
private final Type generatedType; private final Type generatedType;
// CHECKSTYLE:OFF
protected GeneratedType(TypeFactory typeFactory, String packageName, String name, String superClassName, protected GeneratedType(TypeFactory typeFactory, String packageName, String name, String superClassName,
String interfaceName, String interfaceName,
List<MappingMethod> methods, List<MappingMethod> methods,
List<? extends ModelElement> fields, List<? extends ModelElement> fields,
boolean suppressGeneratorTimestamp, Options options,
VersionInformation versionInformation,
Accessibility accessibility, Accessibility accessibility,
SortedSet<Type> extraImportedTypes) { SortedSet<Type> extraImportedTypes) {
this.packageName = packageName; this.packageName = packageName;
@ -79,12 +79,16 @@ public abstract class GeneratedType extends ModelElement {
this.methods = methods; this.methods = methods;
this.fields = fields; this.fields = fields;
this.suppressGeneratorTimestamp = suppressGeneratorTimestamp; this.suppressGeneratorTimestamp = options.isSuppressGeneratorTimestamp();
this.suppressGeneratorVersionComment = options.isSuppressGeneratorVersionComment();
this.versionInformation = versionInformation;
this.accessibility = accessibility; this.accessibility = accessibility;
this.generatedType = typeFactory.getType( Generated.class ); this.generatedType = typeFactory.getType( Generated.class );
} }
// CHECKSTYLE:ON
public String getPackageName() { public String getPackageName() {
return packageName; return packageName;
} }
@ -121,12 +125,16 @@ public abstract class GeneratedType extends ModelElement {
return suppressGeneratorTimestamp; return suppressGeneratorTimestamp;
} }
public Accessibility getAccessibility() { public boolean isSuppressGeneratorVersionComment() {
return accessibility; return suppressGeneratorVersionComment;
} }
public String getComments() { public VersionInformation getVersionInformation() {
return COMMENTS; return versionInformation;
}
public Accessibility getAccessibility() {
return accessibility;
} }
@Override @Override
@ -179,23 +187,4 @@ public abstract class GeneratedType extends ModelElement {
addWithDependents( collection, type ); addWithDependents( collection, type );
} }
} }
private static String initComment() {
String result = null;
try {
Enumeration<URL> resources = GeneratedType.class.getClassLoader().getResources( "META-INF/MANIFEST.MF" );
while ( resources.hasMoreElements() ) {
Manifest manifest = new Manifest( resources.nextElement().openStream() );
String resultValue = manifest.getMainAttributes().getValue( COMMENT_TAG );
if (resultValue != null ) {
result = COMMENT_TAG + ": " + resultValue;
break;
}
}
}
catch ( IOException ex ) {
return result;
}
return result;
}
} }

View File

@ -20,12 +20,16 @@ package org.mapstruct.ap.model;
import java.util.List; import java.util.List;
import java.util.SortedSet; import java.util.SortedSet;
import javax.lang.model.element.ElementKind; import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements; import javax.lang.model.util.Elements;
import org.mapstruct.ap.model.common.Accessibility; import org.mapstruct.ap.model.common.Accessibility;
import org.mapstruct.ap.model.common.Type; import org.mapstruct.ap.model.common.Type;
import org.mapstruct.ap.model.common.TypeFactory; import org.mapstruct.ap.model.common.TypeFactory;
import org.mapstruct.ap.option.Options;
import org.mapstruct.ap.version.VersionInformation;
/** /**
* Represents a type implementing a mapper interface (annotated with {@code @Mapper}). This is the root object of the * Represents a type implementing a mapper interface (annotated with {@code @Mapper}). This is the root object of the
@ -41,10 +45,11 @@ public class Mapper extends GeneratedType {
private final List<MapperReference> referencedMappers; private final List<MapperReference> referencedMappers;
private final Decorator decorator; private final Decorator decorator;
//CHECKSTYLE:OFF @SuppressWarnings( "checkstyle:parameternumber" )
private Mapper(TypeFactory typeFactory, String packageName, String name, String superClassName, private Mapper(TypeFactory typeFactory, String packageName, String name, String superClassName,
String interfaceName, List<MappingMethod> methods, boolean suppressGeneratorTimestamp, String interfaceName, List<MappingMethod> methods, Options options,
Accessibility accessibility, List<MapperReference> referencedMappers, Decorator decorator, VersionInformation versionInformation, Accessibility accessibility,
List<MapperReference> referencedMappers, Decorator decorator,
SortedSet<Type> extraImportedTypes ) { SortedSet<Type> extraImportedTypes ) {
super( super(
@ -55,7 +60,8 @@ public class Mapper extends GeneratedType {
interfaceName, interfaceName,
methods, methods,
referencedMappers, referencedMappers,
suppressGeneratorTimestamp, options,
versionInformation,
accessibility, accessibility,
extraImportedTypes extraImportedTypes
); );
@ -73,7 +79,8 @@ public class Mapper extends GeneratedType {
private SortedSet<Type> extraImportedTypes; private SortedSet<Type> extraImportedTypes;
private Elements elementUtils; private Elements elementUtils;
private boolean suppressGeneratorTimestamp; private Options options;
private VersionInformation versionInformation;
private Decorator decorator; private Decorator decorator;
public Builder element(TypeElement element) { public Builder element(TypeElement element) {
@ -91,8 +98,13 @@ public class Mapper extends GeneratedType {
return this; return this;
} }
public Builder suppressGeneratorTimestamp(boolean suppressGeneratorTimestamp) { public Builder options(Options options) {
this.suppressGeneratorTimestamp = suppressGeneratorTimestamp; this.options = options;
return this;
}
public Builder versionInformation(VersionInformation versionInformation) {
this.versionInformation = versionInformation;
return this; return this;
} }
@ -127,7 +139,8 @@ public class Mapper extends GeneratedType {
element.getKind() != ElementKind.INTERFACE ? element.getSimpleName().toString() : null, element.getKind() != ElementKind.INTERFACE ? element.getSimpleName().toString() : null,
element.getKind() == ElementKind.INTERFACE ? element.getSimpleName().toString() : null, element.getKind() == ElementKind.INTERFACE ? element.getSimpleName().toString() : null,
mappingMethods, mappingMethods,
suppressGeneratorTimestamp, options,
versionInformation,
Accessibility.fromModifiers( element.getModifiers() ), Accessibility.fromModifiers( element.getModifiers() ),
mapperReferences, mapperReferences,
decorator, decorator,

View File

@ -27,12 +27,15 @@ package org.mapstruct.ap.option;
*/ */
public class Options { public class Options {
private final boolean suppressGeneratorTimestamp; private final boolean suppressGeneratorTimestamp;
private final boolean suppressGeneratorVersionComment;
private final ReportingPolicy unmappedTargetPolicy; private final ReportingPolicy unmappedTargetPolicy;
private final String defaultComponentModel; private final String defaultComponentModel;
public Options(boolean suppressGeneratorTimestamp, ReportingPolicy unmappedTargetPolicy, public Options(boolean suppressGeneratorTimestamp, boolean suppressGeneratorVersionComment,
ReportingPolicy unmappedTargetPolicy,
String defaultComponentModel) { String defaultComponentModel) {
this.suppressGeneratorTimestamp = suppressGeneratorTimestamp; this.suppressGeneratorTimestamp = suppressGeneratorTimestamp;
this.suppressGeneratorVersionComment = suppressGeneratorVersionComment;
this.unmappedTargetPolicy = unmappedTargetPolicy; this.unmappedTargetPolicy = unmappedTargetPolicy;
this.defaultComponentModel = defaultComponentModel; this.defaultComponentModel = defaultComponentModel;
} }
@ -41,6 +44,10 @@ public class Options {
return suppressGeneratorTimestamp; return suppressGeneratorTimestamp;
} }
public boolean isSuppressGeneratorVersionComment() {
return suppressGeneratorVersionComment;
}
public ReportingPolicy getUnmappedTargetPolicy() { public ReportingPolicy getUnmappedTargetPolicy() {
return unmappedTargetPolicy; return unmappedTargetPolicy;
} }

View File

@ -30,18 +30,21 @@ import javax.tools.Diagnostic.Kind;
import org.mapstruct.ap.model.common.TypeFactory; import org.mapstruct.ap.model.common.TypeFactory;
import org.mapstruct.ap.option.Options; import org.mapstruct.ap.option.Options;
import org.mapstruct.ap.processor.ModelElementProcessor.ProcessorContext;
import org.mapstruct.ap.version.VersionInformation;
/** /**
* Default implementation of the processor context. * Default implementation of the processor context.
* *
* @author Gunnar Morling * @author Gunnar Morling
*/ */
public class DefaultModelElementProcessorContext implements ModelElementProcessor.ProcessorContext { public class DefaultModelElementProcessorContext implements ProcessorContext {
private final ProcessingEnvironment processingEnvironment; private final ProcessingEnvironment processingEnvironment;
private final DelegatingMessager messager; private final DelegatingMessager messager;
private final Options options; private final Options options;
private final TypeFactory typeFactory; private final TypeFactory typeFactory;
private final VersionInformation versionInformation;
public DefaultModelElementProcessorContext(ProcessingEnvironment processingEnvironment, Options options) { public DefaultModelElementProcessorContext(ProcessingEnvironment processingEnvironment, Options options) {
this.processingEnvironment = processingEnvironment; this.processingEnvironment = processingEnvironment;
@ -51,6 +54,7 @@ public class DefaultModelElementProcessorContext implements ModelElementProcesso
processingEnvironment.getTypeUtils() processingEnvironment.getTypeUtils()
); );
this.options = options; this.options = options;
this.versionInformation = DefaultVersionInformation.fromProcessingEnvironment( processingEnvironment );
} }
@Override @Override
@ -83,6 +87,11 @@ public class DefaultModelElementProcessorContext implements ModelElementProcesso
return options; return options;
} }
@Override
public VersionInformation getVersionInformation() {
return versionInformation;
}
@Override @Override
public boolean isErroneous() { public boolean isErroneous() {
return messager.isErroneous(); return messager.isErroneous();

View File

@ -0,0 +1,199 @@
/**
* 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.processor;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.jar.Manifest;
import javax.annotation.processing.ProcessingEnvironment;
import org.mapstruct.ap.version.VersionInformation;
/**
* Provides information about the processor version and the processor context implementation version.
* <p>
* Separated into an interface and this implementation to avoid cyclic dependencies between the processor package and
* the model package.
*
* @author Andreas Gudian
*/
public class DefaultVersionInformation implements VersionInformation {
private static final String JAVAC_PE_CLASS = "com.sun.tools.javac.processing.JavacProcessingEnvironment";
private static final String JDT_IDE_PE_CLASS =
"org.eclipse.jdt.internal.apt.pluggable.core.dispatch.IdeBuildProcessingEnvImpl";
private static final String JDT_BATCH_PE_CLASS =
"org.eclipse.jdt.internal.compiler.apt.dispatch.BatchProcessingEnvImpl";
private static final String MAP_STRUCT_VERSION = initMapStructVersion();
private final String runtimeVersion;
private final String runtimeVendor;
private final String compiler;
DefaultVersionInformation(String runtimeVersion, String runtimeVendor, String compiler) {
this.runtimeVersion = runtimeVersion;
this.runtimeVendor = runtimeVendor;
this.compiler = compiler;
}
@Override
public String getRuntimeVersion() {
return this.runtimeVersion;
}
@Override
public String getRuntimeVendor() {
return this.runtimeVendor;
}
@Override
public String getMapStructVersion() {
return MAP_STRUCT_VERSION;
}
@Override
public String getCompiler() {
return this.compiler;
}
static DefaultVersionInformation fromProcessingEnvironment(ProcessingEnvironment processingEnv) {
String runtimeVersion = System.getProperty( "java.version" );
String runtimeVendor = System.getProperty( "java.vendor" );
String compiler = getCompiler( processingEnv );
return new DefaultVersionInformation( runtimeVersion, runtimeVendor, compiler );
}
private static String getCompiler(ProcessingEnvironment processingEnv) {
String className = processingEnv.getClass().getName();
if ( className.equals( JAVAC_PE_CLASS ) ) {
return "javac";
}
if ( className.equals( JDT_IDE_PE_CLASS ) ) {
// the processing environment for the IDE integrated APT is in a different bundle than the APT classes
return "Eclipse JDT (IDE) " + getLibraryName( processingEnv.getTypeUtils().getClass(), true );
}
if ( className.equals( JDT_BATCH_PE_CLASS ) ) {
return "Eclipse JDT (Batch) " + getLibraryName( processingEnv.getClass(), true );
}
return processingEnv.getClass().getSimpleName() + " from " + getLibraryName( processingEnv.getClass(), false );
}
private static String getLibraryName(Class<?> clazz, boolean preferVersionOnly) {
String classFileName = asClassFileName( clazz.getName() );
URL resource = clazz.getClassLoader().getResource( classFileName );
Manifest manifest = openManifest( classFileName, resource );
if ( preferVersionOnly && manifest != null ) {
String version = manifest.getMainAttributes().getValue( "Bundle-Version" );
if ( version != null ) {
return version;
}
}
if ( "jar".equals( resource.getProtocol() ) ) {
return extractJarFileName( resource.getFile() );
}
else if ( "jrt".equals( resource.getProtocol() ) ) {
return extractJrtModuleName( resource );
}
else if ( "bundleresource".equals( resource.getProtocol() ) && manifest != null ) {
return extractBundleName( manifest );
}
return resource.toExternalForm();
}
private static Manifest openManifest(String classFileName, URL resource) {
try {
URL manifestUrl = createManifestUrl( classFileName, resource );
return new Manifest( manifestUrl.openStream() );
}
catch ( IOException e ) {
return null;
}
}
private static String extractBundleName(Manifest manifest) {
String version = manifest.getMainAttributes().getValue( "Bundle-Version" );
String symbolicName = manifest.getMainAttributes().getValue( "Bundle-SymbolicName" );
int semicolon = symbolicName.indexOf( ';' );
if ( semicolon > 0 ) {
symbolicName = symbolicName.substring( 0, semicolon );
}
return symbolicName + "_" + version;
}
private static String extractJrtModuleName(URL resource) {
// JDK 9 style, e.g. jrt:/jdk.compiler/com/sun/tools/javac/processing/JavacProcessingEnvironment.class
int moduleNameSeparator = resource.getFile().indexOf( '/', 1 );
if ( moduleNameSeparator > 1 ) {
return resource.getFile().substring( 1, moduleNameSeparator );
}
return resource.toExternalForm();
}
private static URL createManifestUrl(String classFileName, URL resource) throws MalformedURLException {
String classUrlString = resource.toExternalForm();
String baseFileUrl = classUrlString.substring( 0, classUrlString.length() - classFileName.length() );
return new URL( baseFileUrl + "META-INF/MANIFEST.MF" );
}
private static String asClassFileName(String className) {
return className.replace( '.', '/' ) + ".class";
}
private static String extractJarFileName(String file) {
int excl = file.indexOf( '!' );
if ( excl > 0 ) {
String fullFileName = file.substring( 0, excl );
// it's an URL, so it's not the system path separator char:
int lastPathSep = fullFileName.lastIndexOf( '/' );
if ( lastPathSep > 0 && lastPathSep < fullFileName.length() ) {
return fullFileName.substring( lastPathSep + 1 );
}
}
return file;
}
private static String initMapStructVersion() {
String classFileName = asClassFileName( DefaultVersionInformation.class.getName() );
URL resource = DefaultVersionInformation.class.getClassLoader().getResource( classFileName );
Manifest manifest = openManifest( classFileName, resource );
if ( null != manifest ) {
String version = manifest.getMainAttributes().getValue( "Implementation-Version" );
if ( version != null ) {
return version;
}
}
return "";
}
}

View File

@ -23,6 +23,7 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
import javax.annotation.processing.Messager; import javax.annotation.processing.Messager;
import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;
@ -56,6 +57,7 @@ import org.mapstruct.ap.prism.MapperPrism;
import org.mapstruct.ap.processor.creation.MappingResolverImpl; import org.mapstruct.ap.processor.creation.MappingResolverImpl;
import org.mapstruct.ap.util.MapperConfig; import org.mapstruct.ap.util.MapperConfig;
import org.mapstruct.ap.util.Strings; import org.mapstruct.ap.util.Strings;
import org.mapstruct.ap.version.VersionInformation;
/** /**
* A {@link ModelElementProcessor} which creates a {@link Mapper} from the given * A {@link ModelElementProcessor} which creates a {@link Mapper} from the given
@ -69,6 +71,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
private Types typeUtils; private Types typeUtils;
private Messager messager; private Messager messager;
private Options options; private Options options;
private VersionInformation versionInformation;
private TypeFactory typeFactory; private TypeFactory typeFactory;
private MappingBuilderContext mappingContext; private MappingBuilderContext mappingContext;
@ -78,6 +81,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
this.typeUtils = context.getTypeUtils(); this.typeUtils = context.getTypeUtils();
this.messager = context.getMessager(); this.messager = context.getMessager();
this.options = context.getOptions(); this.options = context.getOptions();
this.versionInformation = context.getVersionInformation();
this.typeFactory = context.getTypeFactory(); this.typeFactory = context.getTypeFactory();
List<MapperReference> mapperReferences = initReferencedMappers( mapperTypeElement ); List<MapperReference> mapperReferences = initReferencedMappers( mapperTypeElement );
@ -140,7 +144,8 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
.element( element ) .element( element )
.mappingMethods( mappingMethods ) .mappingMethods( mappingMethods )
.mapperReferences( mapperReferences ) .mapperReferences( mapperReferences )
.suppressGeneratorTimestamp( options.isSuppressGeneratorTimestamp() ) .options( options )
.versionInformation( versionInformation )
.decorator( getDecorator( element, methods ) ) .decorator( getDecorator( element, methods ) )
.typeFactory( typeFactory ) .typeFactory( typeFactory )
.elementUtils( elementUtils ) .elementUtils( elementUtils )
@ -221,7 +226,8 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
decoratorPrism, decoratorPrism,
mappingMethods, mappingMethods,
hasDelegateConstructor, hasDelegateConstructor,
options.isSuppressGeneratorTimestamp() options,
versionInformation
); );
} }

View File

@ -27,6 +27,7 @@ import javax.tools.Diagnostic.Kind;
import org.mapstruct.ap.model.common.TypeFactory; import org.mapstruct.ap.model.common.TypeFactory;
import org.mapstruct.ap.option.Options; import org.mapstruct.ap.option.Options;
import org.mapstruct.ap.version.VersionInformation;
/** /**
* A processor which performs one task of the mapper generation, e.g. retrieving * A processor which performs one task of the mapper generation, e.g. retrieving
@ -62,6 +63,8 @@ public interface ModelElementProcessor<P, R> {
Options getOptions(); Options getOptions();
VersionInformation getVersionInformation();
/** /**
* Whether the currently processed mapper type is erroneous which is the * Whether the currently processed mapper type is erroneous which is the
* case if at least one diagnostic with {@link Kind#ERROR} is reported * case if at least one diagnostic with {@link Kind#ERROR} is reported

View File

@ -0,0 +1,31 @@
/**
* 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.version;
/**
* Provides information about the processor version and the processor context implementation version
*
* @author Andreas Gudian
*/
public interface VersionInformation {
String getRuntimeVersion();
String getRuntimeVendor();
String getMapStructVersion();
String getCompiler();
}

View File

@ -0,0 +1,24 @@
/**
* 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.
*/
/**
* <p>
* Provides various version information
* </p>
*/
package org.mapstruct.ap.version;

View File

@ -26,8 +26,8 @@ import ${importedType.importName};
@Generated( @Generated(
value = "org.mapstruct.ap.MappingProcessor"<#if suppressGeneratorTimestamp == false>, value = "org.mapstruct.ap.MappingProcessor"<#if suppressGeneratorTimestamp == false>,
date = "${.now?string("yyyy-MM-dd'T'HH:mm:ssZ")}"</#if><#if comments??>, date = "${.now?string("yyyy-MM-dd'T'HH:mm:ssZ")}"</#if><#if suppressGeneratorVersionComment == false>,
comments = "${comments}"</#if> comments = "version: ${versionInformation.mapStructVersion}, compiler: ${versionInformation.compiler}, environment: Java ${versionInformation.runtimeVersion} (${versionInformation.runtimeVendor})"</#if>
) )
<#list annotations as annotation> <#list annotations as annotation>
<#nt><@includeModel object=annotation/> <#nt><@includeModel object=annotation/>

View File

@ -0,0 +1,30 @@
/**
* 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.test.versioninfo;
import org.mapstruct.Mapper;
/**
* @author Andreas Gudian
*
*/
@Mapper
public interface SimpleMapper {
Object toObject(Object object);
}

View File

@ -0,0 +1,72 @@
/**
* 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.test.versioninfo;
import org.junit.Rule;
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.ProcessorOption;
import org.mapstruct.ap.testutil.compilation.annotation.ProcessorOptions;
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
import org.mapstruct.ap.testutil.runner.GeneratedSource;
/**
* @author Andreas Gudian
*
*/
@RunWith( AnnotationProcessorTestRunner.class )
@IssueKey( "424" )
@WithClasses( SimpleMapper.class )
public class VersionInfoTest {
private final GeneratedSource generatedSource = new GeneratedSource();
@Rule
public GeneratedSource getGeneratedSource() {
return generatedSource;
}
@Test
@ProcessorOption( name = "mapstruct.suppressGeneratorVersionInfoComment", value = "true" )
public void includesNoComment() {
generatedSource.forMapper( SimpleMapper.class ).content()
.contains( "date = \"" )
.doesNotContain( "comments = \"version: " );
}
@Test
@ProcessorOptions( {
@ProcessorOption( name = "mapstruct.suppressGeneratorVersionInfoComment", value = "true" ),
@ProcessorOption( name = "mapstruct.suppressGeneratorTimestamp", value = "true" )
} )
public void includesNoCommentAndNoTimestamp() {
generatedSource.forMapper( SimpleMapper.class ).content()
.doesNotContain( "date = \"" )
.doesNotContain( "comments = \"version: " );
}
@Test
public void includesCommentAndTimestamp() {
generatedSource.forMapper( SimpleMapper.class ).content()
.contains( "date = \"" )
.contains( "comments = \"version: " );
}
}