Package com.elevenware.redcorn

Source Code of com.elevenware.redcorn.DependencyInstantiationOrdering$Holder

package com.elevenware.redcorn;

import com.elevenware.redcorn.beans.BeanDefinition;
import com.elevenware.redcorn.beans.ConstructorModel;

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class DependencyInstantiationOrdering {

    private final List<BeanDefinition> beans;

    public DependencyInstantiationOrdering(List<BeanDefinition> beans) {
        this.beans = beans;
    }

    public List<Holder> getGreedyConstructorsFrom(List<BeanDefinition> beans, List<Class<?>> allTypes) {
        List<Holder> constructors  = new ArrayList<>();
        for(BeanDefinition bean: beans) {
            ConstructorModel model = bean.getConstructorModel();
            constructors.add(new Holder(model.findBestConstructorsForTypes(allTypes, bean.getConstructorArgs()), bean));
        }
        return constructors;
    }

    private List<Class<?>> getTypesFrom(List<BeanDefinition> beans) {
        List<Class<?>> types = new ArrayList<>();
        for(BeanDefinition bean: beans) {
            types.add(bean.getType());
        }
        return types;
    }

    public List<BeanDefinition> sort() {
        List<Class<?>> allTypes = getTypesFrom(beans);
        List<BeanDefinition> sortedBeans = new ArrayList<>();
        assertAllSatisfiable(beans, allTypes);
        List<Holder> holders = getGreedyConstructorsFrom(beans, allTypes);
        Iterator<Holder> iter = holders.iterator();
        while(iter.hasNext()){
            Holder holder = iter.next();
            if(holder.bean.canInstantiate()) {
                sortedBeans.add(holder.bean);
                iter.remove();
            }
        }
        int i = 0;

        while(!holders.isEmpty()) {
            List<Class<?>> currentlyReady = getTypesFrom(sortedBeans);
            if( i >= holders.size() ) {
                i = 0;
            }
            Holder holder = holders.get(i);

            if(holder.bean.getConstructorModel().findBestConstructorsForTypes(currentlyReady, holder.bean.getConstructorArgs() ) != null || holder.bean.canInstantiate()) {
                sortedBeans.add(holder.bean);
                holders.remove(i);
            }
            i++;
        }
        return sortedBeans;
    }

    private boolean inSorted(String ref, List<BeanDefinition> sortedBeans) {
        for(BeanDefinition def: sortedBeans) {
            if(def.getName().equals(ref)) {
                return true;
            }
        }
        return false;
    }

    private boolean namedConstructorsLeft(List<Holder> holders) {
        for(Holder holder: holders) {
            if(holder.bean.getConstructorRefs().size() > 0) {
                return true;
            }
        }
        return false;
    }

    private void assertAllSatisfiable(List<BeanDefinition> beans, List<Class<?>> allTypes) {
        for(BeanDefinition bean: beans) {
            Constructor best = bean.getConstructorModel().findBestConstructorsForTypes(allTypes, bean.getConstructorArgs());
            if(best == null) {
                throw new RuntimeException("Could never satisfy dependencies for " + bean);
            }
        }
    }

    public static class Holder {
        Constructor best;
        BeanDefinition bean;

        public Holder(Constructor bestConstructorsForTypes, BeanDefinition bean) {
            this.best = bestConstructorsForTypes;
            this.bean = bean;
        }
    }

}
TOP

Related Classes of com.elevenware.redcorn.DependencyInstantiationOrdering$Holder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.