All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nohope.spring.app.HandlerWithStorage Maven / Gradle / Ivy

The newest version!
package org.nohope.spring.app;

import org.springframework.context.ConfigurableApplicationContext;
import org.nohope.reflection.TypeReference;

import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;

import static org.nohope.reflection.IntrospectionUtils.cast;
import static org.nohope.reflection.IntrospectionUtils.instanceOf;

/**
 * @author ketoth xupack
 * @since 10/17/12 11:16 PM
 */
public abstract class HandlerWithStorage extends Handler {
    private final Map> modules = new HashMap<>();

    /**
     * @return Map of descriptors of all the available modules
     */
    @Nonnull
    public final Map> getModuleDescriptors() {
        return new TreeMap<>(modules);
    }

    protected final  List> getDescriptors(final Class clazz) {
        return getDescriptors(clazz, modules.values());
    }

    protected final  Map getModules(final Class clazz) {
        final Map result = new HashMap<>();
        for (final ModuleDescriptor d: getDescriptors(clazz, modules.values())) {
            result.put(d.getName(), d.getModule());
        }
        return result;
    }

    /**
     * @param clazz module class
     * @param  supertype of modules to be filtered
     * @return All the implementations of given superclass
     */
    protected final  List getImplementations(final Class clazz) {
        return getImplementations(clazz, modules.values());
    }

    static  List> getDescriptors(
            final Class clazz,
            final Collection> source) {

        final List> ret = new ArrayList<>();
        for (final ModuleDescriptor obj : source) {
            final M module = obj.getModule();
            if (instanceOf(module.getClass(), clazz)) {
                ret.add(cast(obj, new TypeReference>() {}));
            }
        }
        return ret;
    }


    static  List getImplementations(final Class clazz,
                                             final Collection> source) {
        final List ret = new ArrayList<>();
        for (final ModuleDescriptor obj : source) {
            final M module = obj.getModule();
            if (instanceOf(module.getClass(), clazz)) {
                ret.add(cast(module, clazz));
            }
        }
        return ret;
    }

    protected M getModule(final String moduleName) {
        return modules.get(moduleName).getModule();
    }

    protected  Subtype getModule(final Class clazz,
                                                    final String moduleName) {
        final ModuleDescriptor md = modules.get(moduleName);
        if (clazz.isAssignableFrom(md.getModule().getClass())) {
            @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"})
            final Subtype module = (Subtype) md.getModule();
            return module;
        }
        throw new IllegalArgumentException("No module '"+moduleName+"' with given type "+clazz.getCanonicalName());
    }

    /**
     * This method executed when app successfully instantiated module using it's context.
     * Here is a good place to pass do some module postprocessing.
     *
     * @param module     module class
     * @param ctx        final module context
     * @param properties module descriptor
     * @param name       module name
     */
    @Override
    protected final void onModuleCreated(@Nonnull final M module,
                                         @Nonnull final ConfigurableApplicationContext ctx,
                                         @Nonnull final Properties properties,
                                         @Nonnull final String name) {
        final ModuleDescriptor descriptor = new ModuleDescriptor<>(name, module, properties, ctx);
        modules.put(name, descriptor);
        onModuleAdded(descriptor);
    }

    protected final void onModuleAdded(@Nonnull final ModuleDescriptor descriptor) {
    }
}