/*
* Copyright 2014 mango.jfaster.org
*
* The Mango Project licenses this file to you 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.jfaster.mango.plugin.spring;
import org.jfaster.mango.annotation.DB;
import org.jfaster.mango.util.logging.InternalLogger;
import org.jfaster.mango.util.logging.InternalLoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author ash
*/
final public class MangoDaoScanner implements BeanFactoryPostProcessor {
private final static InternalLogger logger = InternalLoggerFactory.getInstance(MangoDaoScanner.class);
private static final List<String> DAO_ENDS = Arrays.asList("Dao", "DAO");
List<String> locationPatterns = new ArrayList<String>();
Class<?> factoryBeanClass = DefaultMangoFactoryBean.class;
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
DefaultListableBeanFactory dlbf = (DefaultListableBeanFactory) beanFactory;
for (Class<?> daoClass : findMangoDaoClasses()) {
GenericBeanDefinition bf = new GenericBeanDefinition();
bf.setBeanClassName(daoClass.getName());
MutablePropertyValues pvs = bf.getPropertyValues();
pvs.addPropertyValue("daoClass", daoClass);
bf.setBeanClass(factoryBeanClass);
bf.setPropertyValues(pvs);
bf.setLazyInit(false);
dlbf.registerBeanDefinition(daoClass.getName(), bf);
}
}
private List<Class<?>> findMangoDaoClasses() {
try {
List<Class<?>> daos = new ArrayList<Class<?>>();
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resourcePatternResolver);
for (String locationPattern : locationPatterns) {
Resource[] rs = resourcePatternResolver.getResources(locationPattern);
for (Resource r : rs) {
MetadataReader reader = metadataReaderFactory.getMetadataReader(r);
AnnotationMetadata annotationMD = reader.getAnnotationMetadata();
if (annotationMD.hasAnnotation(DB.class.getName())) {
ClassMetadata clazzMD = reader.getClassMetadata();
daos.add(Class.forName(clazzMD.getClassName()));
}
}
}
return daos;
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
public void setPackages(List<String> packages) {
for (String p : packages) {
for (String daoEnd : DAO_ENDS) {
String locationPattern = "classpath*:" + p.replaceAll("\\.", "/") + "/**/*" + daoEnd + ".class";
logger.info("trnas package[" + p + "] to locationPattern[" + locationPattern + "]");
locationPatterns.add(locationPattern);
}
}
}
public void setFactoryBeanClass(Class<?> factoryBeanClass) {
this.factoryBeanClass = factoryBeanClass;
}
}