/** * Copyright 2012-2017 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.internal.model; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.SortedSet; import java.util.TreeSet; import javax.lang.model.type.TypeKind; import org.mapstruct.ap.internal.model.common.Accessibility; import org.mapstruct.ap.internal.model.common.ModelElement; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; import org.mapstruct.ap.internal.option.Options; import org.mapstruct.ap.internal.util.Strings; import org.mapstruct.ap.internal.version.VersionInformation; /** * A type generated by MapStruct, e.g. representing a mapper type. * * @author Gunnar Morling */ public abstract class GeneratedType extends ModelElement { private static final String JAVA_LANG_PACKAGE = "java.lang"; private final String packageName; private final String name; private final String superClassName; private final String interfacePackage; private final String interfaceName; private final List<Annotation> annotations; private final List<MappingMethod> methods; private final SortedSet<Type> extraImportedTypes; private final boolean suppressGeneratorTimestamp; private final boolean suppressGeneratorVersionComment; private final VersionInformation versionInformation; private final Accessibility accessibility; private List<? extends Field> fields; private Constructor constructor; /** * Type representing the {@code @Generated} annotation */ private final Type generatedType; private final boolean generatedTypeAvailable; // CHECKSTYLE:OFF protected GeneratedType(TypeFactory typeFactory, String packageName, String name, String superClassName, String interfacePackage, String interfaceName, List<MappingMethod> methods, List<? extends Field> fields, Options options, VersionInformation versionInformation, Accessibility accessibility, SortedSet<Type> extraImportedTypes, Constructor constructor ) { this.packageName = packageName; this.name = name; this.superClassName = superClassName; this.interfacePackage = interfacePackage; this.interfaceName = interfaceName; this.extraImportedTypes = extraImportedTypes; this.annotations = new ArrayList<Annotation>(); this.methods = methods; this.fields = fields; this.suppressGeneratorTimestamp = options.isSuppressGeneratorTimestamp(); this.suppressGeneratorVersionComment = options.isSuppressGeneratorVersionComment(); this.versionInformation = versionInformation; this.accessibility = accessibility; this.generatedTypeAvailable = typeFactory.isTypeAvailable( "javax.annotation.Generated" ); if ( generatedTypeAvailable ) { this.generatedType = typeFactory.getType( "javax.annotation.Generated" ); } else { this.generatedType = null; } this.constructor = constructor; } // CHECKSTYLE:ON public String getPackageName() { return packageName; } public boolean hasPackageName() { return !Strings.isEmpty( packageName ); } public String getName() { return name; } public String getSuperClassName() { return superClassName; } public String getInterfacePackage() { return interfacePackage; } public String getInterfaceName() { return interfaceName; } public List<Annotation> getAnnotations() { return annotations; } public void addAnnotation(Annotation annotation) { annotations.add( annotation ); } public List<MappingMethod> getMethods() { return methods; } public List<? extends Field> getFields() { return fields; } public void setFields(List<? extends Field> fields) { this.fields = fields; } public boolean isSuppressGeneratorTimestamp() { return suppressGeneratorTimestamp; } public boolean isSuppressGeneratorVersionComment() { return suppressGeneratorVersionComment; } public boolean isGeneratedTypeAvailable() { return generatedTypeAvailable; } public VersionInformation getVersionInformation() { return versionInformation; } public Accessibility getAccessibility() { return accessibility; } @Override public SortedSet<Type> getImportTypes() { SortedSet<Type> importedTypes = new TreeSet<Type>(); addIfImportRequired( importedTypes, generatedType ); for ( MappingMethod mappingMethod : methods ) { for ( Type type : mappingMethod.getImportTypes() ) { addIfImportRequired( importedTypes, type ); } } for ( Field field : fields ) { if ( field.isTypeRequiresImport() ) { for ( Type type : field.getImportTypes() ) { addIfImportRequired( importedTypes, type ); } } } for ( Annotation annotation : annotations ) { addIfImportRequired( importedTypes, annotation.getType() ); } for ( Type extraImport : extraImportedTypes ) { addIfImportRequired( importedTypes, extraImport ); } return importedTypes; } public Constructor getConstructor() { return constructor; } public void removeConstructor() { constructor = null; } protected void addIfImportRequired(Collection<Type> collection, Type typeToAdd) { if ( typeToAdd == null ) { return; } if ( needsImportDeclaration( typeToAdd ) ) { collection.add( typeToAdd ); } } private boolean needsImportDeclaration(Type typeToAdd) { if ( !typeToAdd.isImported() ) { return false; } if ( typeToAdd.getTypeMirror().getKind() != TypeKind.DECLARED ) { return false; } if ( typeToAdd.getPackageName() != null ) { if ( typeToAdd.getPackageName().startsWith( JAVA_LANG_PACKAGE ) ) { return false; } if ( typeToAdd.getPackageName().equals( packageName ) ) { if ( !typeToAdd.getTypeElement().getNestingKind().isNested() ) { return false; } } } return true; } }