package pl.openrest.dto.mappers.generator;

import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.reflections.Reflections;
import org.reflections.scanners.Scanner;
import org.reflections.scanners.TypeAnnotationsScanner;
import org.springframework.util.ReflectionUtils.FieldFilter;

import pl.openrest.dto.annotations.Dto;
import pl.openrest.generator.commons.AbstractGeneratorMojo;
import pl.openrest.generator.commons.Configuration;
import pl.openrest.generator.commons.type.CompositeFieldFilter;
import pl.openrest.generator.commons.type.NonFinalOrStaticFieldFilter;
import pl.openrest.generator.commons.type.TypeResolver;

@Mojo(name = "process", defaultPhase = LifecyclePhase.PROCESS_SOURCES)
public class DtoMappersGeneratorMojo extends AbstractGeneratorMojo {

    @Parameter
    private List<FieldFilter> dtoFieldFilters = new LinkedList<>();

    @Override
    protected void doExecute() throws MojoExecutionException {
        Reflections reflections = configuration.get("reflections");
        TypeResolver defaultTypeResolver = configuration.get("defaultTypeResolver");
        Set<Class<?>> dtoTypes = reflections.getTypesAnnotatedWith(Dto.class);
        for (Class<?> dtoType : dtoTypes) {
            if (defaultTypeResolver.supports(dtoType))
                defaultTypeResolver.resolve(dtoType);
        }
    }

    @Override
    protected Configuration createConfiguration() {
        Configuration configuration = super.createConfiguration();
        configuration.put("dtoFieldFilters", dtoFieldFilters);
        return configuration;
    };

    @Override
    protected void addDefaultTypeResolvers(List<TypeResolver> typeResolvers) {
        DtoMapperResolver dtoMapperResolver = new DtoMapperResolver(new CompositeFieldFilter(dtoFieldFilters));
        typeResolvers.add(dtoMapperResolver);
        super.addDefaultTypeResolvers(typeResolvers);
    }

    @Override
    protected void initializeDefault() {
        if (defaultNamingStrategy == null)
            defaultNamingStrategy = new MapperNamingStrategy();
        super.initializeDefault();
        if (dtoFieldFilters == null) {
            dtoFieldFilters = new LinkedList<>();
        }
        dtoFieldFilters.add(new NonFinalOrStaticFieldFilter());
    }

    @Override
    protected void addDefaultScanners(List<Scanner> scanners) {
        scanners.add(new TypeAnnotationsScanner());
    }

    public void setDtoFieldFilters(List<FieldFilter> dtoFieldFilters) {
        this.dtoFieldFilters = dtoFieldFilters;
    }

}

@@ -328,24 +328,70 @@
 .Parameter;%0A
+import org.apache.maven.project.MavenProject;%0A
 import org.r
@@ -414,16 +414,16 @@
 ctions;%0A
-
 import o
@@ -983,13 +983,13 @@
 ESS_
-SOURC
+CLASS
 ES)%0A
@@ -1142,16 +1142,117 @@
 t%3C%3E();%0A%0A
+    @Parameter(defaultValue = %22$%7Bproject%7D%22, readonly = true)%0A    private MavenProject mavenProject;%0A%0A
     @Ove
@@ -1785,16 +1785,46 @@
 ration()
+ throws MojoExecutionException
  %7B%0A     
@@ -2072,24 +2072,54 @@
 peResolvers)
+ throws MojoExecutionException
  %7B%0A        D
@@ -2380,16 +2380,46 @@
 efault()
+ throws MojoExecutionException
  %7B%0A     
@@ -2532,32 +2532,132 @@
     
-super.initializeDefault(
+if (reflectionsFactory == null)%0A            reflectionsFactory = new ProjectClassPathAwareReflectionsRepository(mavenProject
 );%0A 
@@ -2750,24 +2750,24 @@
 ;%0A        %7D%0A
-
         dtoF
@@ -2814,24 +2814,59 @@
 dFilter());%0A
+        super.initializeDefault();%0A
     %7D%0A%0A    @

Change phase to Process_Classes, change default reflections factory to ProjectClassPathAwareReflectionsFactory