/**
 *    Copyright 2010-2016 the original author or authors.
 *
 *    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.mybatis.spring.annotation;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;

import org.mybatis.spring.mapper.ClassPathMapperScanner;
import org.mybatis.spring.mapper.MapperFactoryBean;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;

/**
 * A {@link ImportBeanDefinitionRegistrar} to allow annotation configuration of
 * MyBatis mapper scanning. Using an @Enable annotation allows beans to be
 * registered via @Component configuration, whereas implementing
 * {@code BeanDefinitionRegistryPostProcessor} will work for XML configuration.
 *
 * @author Michael Lanyon
 * @author Eduardo Macarron
 * 
 * @see MapperFactoryBean
 * @see ClassPathMapperScanner
 * @since 1.2.0
 */
public class MapperScannerRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware {

  private ResourceLoader resourceLoader;

  /**
   * {@inheritDoc}
   */
  @Override
  public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

    AnnotationAttributes annoAttrs = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(MapperScan.class.getName()));
    ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);

    // this check is needed in Spring 3.1
    if (resourceLoader != null) {
      scanner.setResourceLoader(resourceLoader);
    }

    Class<? extends Annotation> annotationClass = annoAttrs.getClass("annotationClass");
    if (!Annotation.class.equals(annotationClass)) {
      scanner.setAnnotationClass(annotationClass);
    }

    Class<?> markerInterface = annoAttrs.getClass("markerInterface");
    if (!Class.class.equals(markerInterface)) {
      scanner.setMarkerInterface(markerInterface);
    }

    Class<? extends BeanNameGenerator> generatorClass = annoAttrs.getClass("nameGenerator");
    if (!BeanNameGenerator.class.equals(generatorClass)) {
      scanner.setBeanNameGenerator(BeanUtils.instantiateClass(generatorClass));
    }

    Class<? extends MapperFactoryBean> mapperFactoryBeanClass = annoAttrs.getClass("factoryBean");
    if (!MapperFactoryBean.class.equals(mapperFactoryBeanClass)) {
      scanner.setMapperFactoryBean(BeanUtils.instantiateClass(mapperFactoryBeanClass));
    }

    scanner.setSqlSessionTemplateBeanName(annoAttrs.getString("sqlSessionTemplateRef"));
    scanner.setSqlSessionFactoryBeanName(annoAttrs.getString("sqlSessionFactoryRef"));

    List<String> basePackages = new ArrayList<>();
    for (String pkg : annoAttrs.getStringArray("value")) {
      if (StringUtils.hasText(pkg)) {
        basePackages.add(pkg);
      }
    }
    for (String pkg : annoAttrs.getStringArray("basePackages")) {
      if (StringUtils.hasText(pkg)) {
        basePackages.add(pkg);
      }
    }
    for (Class<?> clazz : annoAttrs.getClassArray("basePackageClasses")) {
      basePackages.add(ClassUtils.getPackageName(clazz));
    }
    scanner.registerFilters();
    scanner.doScan(StringUtils.toStringArray(basePackages));
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void setResourceLoader(ResourceLoader resourceLoader) {
    this.resourceLoader = resourceLoader;
  }

}

@@ -25,9 +25,9 @@
 -201
-6
+7
  the
@@ -768,20 +768,110 @@
 va.util.
-List
+Arrays;%0Aimport java.util.Collection;%0Aimport java.util.List;%0Aimport java.util.stream.Collectors
 ;%0A%0Aimpor
@@ -1916,16 +1916,49 @@
 acarron%0A
+ * @author Putthiphong Boonphong%0A
  * %0A * @
@@ -2173,16 +2173,171 @@
 oader;%0A%0A
+  /**%0A   * %7B@inheritDoc%7D%0A   */%0A  @Override%0A  public void setResourceLoader(ResourceLoader resourceLoader) %7B%0A    this.resourceLoader = resourceLoader;%0A  %7D%0A%0A
   /**%0A  
@@ -3947,34 +3947,50 @@
 ();%0A    
-for (String pkg : 
+basePackages.addAll(Arrays.stream(
 annoAttr
@@ -4015,28 +4015,23 @@
 value%22))
- %7B%0A      if 
+.filter
 (StringU
@@ -4038,92 +4038,88 @@
 tils
-.
+::
 hasText
-(pkg)) %7B%0A        basePackages.add(pkg);%0A      %7D%0A    %7D%0A    for (String pkg : 
+).collect(Collectors.toList()));%0A    basePackages.addAll(Arrays.stream(
 anno
@@ -4159,20 +4159,15 @@
 s%22))
- %7B%0A      if 
+.filter
 (Str
@@ -4178,33 +4178,54 @@
 tils
-.
+::
 hasText
-(pkg)) %7B%0A   
+).collect(Collectors.toList()));%0A
     
- 
 base
@@ -4240,55 +4240,26 @@
 .add
-(pkg);%0A      %7D%0A    %7D%0A    for (Class%3C?%3E clazz : 
+All(Arrays.stream(
 anno
@@ -4304,33 +4304,12 @@
 s%22))
- %7B%0A      basePackages.add
+.map
 (Cla
@@ -4315,17 +4315,18 @@
 assUtils
-.
+::
 getPacka
@@ -4335,23 +4335,41 @@
 Name
-(clazz
+).collect(Collectors.toList(
 ))
+)
 ;%0A
-    %7D
 %0A   
@@ -4466,161 +4466,6 @@
  %7D%0A%0A
-  /**%0A   * %7B@inheritDoc%7D%0A   */%0A  @Override%0A  public void setResourceLoader(ResourceLoader resourceLoader) %7B%0A    this.resourceLoader = resourceLoader;%0A  %7D%0A%0A
 %7D%0A

Use Java Stream to collect basePackages