org.makersoft.activerecord.bootstrap.Bootstrap.java Source code

Java tutorial

Introduction

Here is the source code for org.makersoft.activerecord.bootstrap.Bootstrap.java

Source

/*
 * @(#)Bootstrap.java 2013-2-22 ?23:33:33
 *
 * Copyright (c) 2011-2013 Makersoft.org all rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 *
 */
package org.makersoft.activerecord.bootstrap;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.makersoft.activerecord.enhancer.PersistenceEnhancer;
import org.scannotation.ClasspathUrlFinder;
import org.scannotation.archiveiterator.Filter;
import org.scannotation.archiveiterator.IteratorFactory;
import org.scannotation.archiveiterator.StreamIterator;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

/**
 * Class description goes here.
 * 
 * @version 2013-2-22 ?6:16:28
 * @author Feng Kuok
 */
public class Bootstrap implements BeanDefinitionRegistryPostProcessor, InitializingBean, ApplicationContextAware {
    private String basePackage = "org.makersoft.activerecord.model";

    private ApplicationContext applicationContext;
    private boolean init;

    public void setBasePackage(String basePackage) {
        this.basePackage = basePackage;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        Assert.notNull(this.basePackage, "Property 'basePackage' is required");
        init();
    }

    private void init() {
        init = true;
        List<InputStream> inputStreams = new ArrayList<InputStream>();
        URL[] urls = getPackagePaths();

        Filter filter = new Filter() {
            public boolean accepts(String filename) {
                if (filename.endsWith(".class")) {
                    return true;
                }

                return false;
            }
        };

        for (URL url : urls) {
            try {
                StreamIterator iterator = IteratorFactory.create(url, filter);

                InputStream stream;
                while ((stream = iterator.next()) != null) {
                    inputStreams.add(stream);
                }
            } catch (IOException e) {

                //throw new RuntimeException(e);
            }
        }

        PersistenceEnhancer enhancer = new PersistenceEnhancer();
        for (InputStream inputStream : inputStreams) {
            try {
                enhancer.enhanceThisClass(inputStream);
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }

    }

    private URL[] getPackagePaths() {
        URL classpathUrl = ClasspathUrlFinder.findClassBase(this.getClass());
        try {
            String classpath = classpathUrl.getPath();
            String testClasspath = classpath.substring(0, classpath.lastIndexOf("classes")) + "test-classes/";

            return new URL[] { new URL("file:" + classpath + basePackage.replaceAll("\\.", "/") + "/"),
                    new URL("file:" + testClasspath + basePackage.replaceAll("\\.", "/") + "/") };

        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {

        Scanner scanner = new Scanner(registry);
        scanner.setResourceLoader(this.applicationContext);

        scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage,
                ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS));

    }

    private final class Scanner extends ClassPathBeanDefinitionScanner {

        public Scanner(BeanDefinitionRegistry registry) {
            super(registry);
        }

        /**
         * Configures parent scanner to search for the right bean. It can search for all class or
         * just for those that implements ShardStrategy or/and those annotated with the
         * annotationClass
         */
        @Override
        protected void registerDefaultFilters() {

            // if specified, use the given annotation and / or marker interface
            // super.addIncludeFilter(new AnnotationTypeFilter(ShardStrategy.class));

            // exclude package-info.java
            super.addExcludeFilter(new TypeFilter() {
                public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
                        throws IOException {
                    String className = metadataReader.getClassMetadata().getClassName();
                    return className.endsWith("package-info");
                }
            });
        }

        /**
         * Calls the parent search that will search and register all the candidates. Then the
         * registered objects are post processed to set them as ShardStrategy.
         */
        @Override
        protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
            Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);

            //         if (beanDefinitions.isEmpty()) {
            //            logger.warn("No Shard Strategy was found in '"
            //                  + ApplicationConfigurer.this.basePackage
            //                  + "' package. Please check your configuration.");
            //         } else {
            if (init == false) {
                init();
            }
            //             GenericBeanDefinition beanDef = new GenericBeanDefinition();
            //             beanDef.setBeanClass(PersistenceHelper.class);
            //             
            //             SqlSessionTemplate sessionTemplate = applicationContext.getBean(SqlSessionTemplate.class);
            //             beanDef.getPropertyValues().add("sqlSessionTemplate", sessionTemplate);
            //
            //             BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(beanDef,"persistenceHelper");
            //             super.registerBeanDefinition(definitionHolder, super.getRegistry());
            // ShardReduceStrategyContext reduceStrategyContext = applicationContext
            // .getBean(ShardReduceStrategyContext.class);
            for (BeanDefinitionHolder holder : beanDefinitions) {
                GenericBeanDefinition definition = (GenericBeanDefinition) holder.getBeanDefinition();

                if (logger.isDebugEnabled()) {
                    logger.debug("Creating Strategy with name '" + holder.getBeanName() + "' and '"
                            + definition.getBeanClassName() + "'.");
                }

                // ShardReduceStrategy reduceStrategy = (ShardReduceStrategy) applicationContext
                // .getBean(holder.getBeanName());
                // ShardedReducer reducer = reduceStrategy.getClass().getAnnotation(
                // ShardedReducer.class);
                //
                // reduceStrategyContext.put(reducer.mapper(), reducer.statements(),
                // reduceStrategy);

            }
            //         }

            return beanDefinitions;
        }

        @Override
        protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
            return (!beanDefinition.getMetadata().isInterface() && beanDefinition.getMetadata().isIndependent());
        }

        @Override
        protected boolean checkCandidate(String beanName, BeanDefinition beanDefinition)
                throws IllegalStateException {
            if (super.checkCandidate(beanName, beanDefinition)) {
                return true;
            } else {
                //            logger.warn("Skipping strategy bean  with name '" + beanName + "' and '"
                //                  + beanDefinition.getBeanClassName()
                //                  + "'. Bean already defined with the same name!");
                return false;
            }
        }
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

    }
}