org.metamorphosis.core.ModuleManager.java Source code

Java tutorial

Introduction

Here is the source code for org.metamorphosis.core.ModuleManager.java

Source

package org.metamorphosis.core;

import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.digester.Digester;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.dispatcher.Dispatcher;
import org.apache.struts2.dispatcher.DispatcherListener;
import org.apache.tiles.Attribute;
import org.apache.tiles.Definition;
import org.apache.tiles.access.TilesAccess;
import com.opensymphony.xwork2.config.Configuration;
import com.opensymphony.xwork2.config.entities.ActionConfig;
import com.opensymphony.xwork2.config.entities.PackageConfig;
import com.opensymphony.xwork2.config.entities.ResultConfig;

public class ModuleManager implements DispatcherListener {

    private List<Module> modules = new ArrayList<Module>();
    private Logger logger = Logger.getLogger(ModuleManager.class.getName());
    private Configuration configuration;
    private ServletContext servletContext;
    private static ModuleManager instance;
    private static final String MODULE_METADATA = "module.xml";

    public ModuleManager() {
        instance = this;
    }

    public ModuleManager(ServletContext servletContext) {
        instance = this;
        this.servletContext = servletContext;
    }

    public void loadModules(final File root) {
        File[] files = root.listFiles();
        if (files != null) {
            for (File folder : files) {
                if (folder.isDirectory())
                    loadModule(folder);
            }
            orderModules();
            monitorRoot(root);
        }
    }

    public void loadModule(File folder) {
        File metadata = new File(folder + "/" + MODULE_METADATA);
        if (metadata.exists()) {
            try {
                final Module module = parse(metadata);
                module.setFolder(folder);
                initModule(module);
                addModule(module);
                monitorModule(module);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private Module parse(File metadata) throws Exception {
        Digester digester = new Digester();
        digester.setValidating(false);
        digester.addObjectCreate("module", Module.class);
        digester.addBeanPropertySetter("module/name");
        digester.addBeanPropertySetter("module/type");
        digester.addBeanPropertySetter("module/url");
        digester.addBeanPropertySetter("module/icon");
        digester.addBeanPropertySetter("module/index", "indexPage");
        digester.addBeanPropertySetter("module/template");
        digester.addBeanPropertySetter("module/main");
        digester.addBeanPropertySetter("module/visible");
        digester.addBeanPropertySetter("module/administrable");
        digester.addBeanPropertySetter("module/cached");
        digester.addBeanPropertySetter("module/order");
        digester.addBeanPropertySetter("module/author");
        digester.addBeanPropertySetter("module/authorEmail");
        digester.addBeanPropertySetter("module/authorUrl");
        digester.addBeanPropertySetter("module/description");
        digester.addBeanPropertySetter("module/creationDate");
        digester.addBeanPropertySetter("module/copyright");
        digester.addBeanPropertySetter("module/license");
        digester.addBeanPropertySetter("module/version");
        digester.addObjectCreate("module/menus/menu", Menu.class);
        digester.addSetProperties("module/menus/menu");
        digester.addObjectCreate("module/menus/menu/menuItem", MenuItem.class);
        digester.addSetProperties("module/menus/menu/menuItem");
        digester.addSetNext("module/menus/menu/menuItem", "addMenuItem");
        digester.addSetNext("module/menus/menu", "addMenu");
        digester.addObjectCreate("module/actions/action", Action.class);
        digester.addSetProperties("module/actions/action");
        digester.addSetProperties("module/actions/action", "class", "className");
        digester.addObjectCreate("module/actions/action/result", Result.class);
        digester.addSetProperties("module/actions/action/result");
        digester.addObjectCreate("module/actions/action/result/param", Parameter.class);
        digester.addSetProperties("module/actions/action/result/param");
        digester.addSetNext("module/actions/action/result/param", "addParameter");
        digester.addCallMethod("module/actions/action/result/param", "setValue", 0);
        digester.addSetNext("module/actions/action/result", "addResult");
        digester.addCallMethod("module/actions/action/result", "setValue", 0);
        digester.addSetNext("module/actions/action", "addAction");
        return (Module) digester.parse(metadata);
    }

    private void initModule(Module module) {
        if (module.getUrl() == null)
            module.setUrl(module.getFolder().getName());
        for (Menu menu : module.getMenus()) {
            for (MenuItem item : menu.getMenuItems()) {
                String url = item.getUrl() != null ? module.getUrl() + "/" + item.getUrl() : module.getUrl();
                item.setUrl(url);
            }
        }
    }

    private void orderModules() {

    }

    private void monitorRoot(final File root) {
        FileMonitor monitor = new FileMonitor(root);
        monitor.addListener(new FileListener() {

            @Override
            public void onCreated(String file) {
                File folder = new File(root + "/" + file);
                if (folder.isDirectory()) {
                    logger.log(Level.INFO, "adding module  : " + folder.getName());
                    final Module module = new Module();
                    module.setFolder(folder);
                    initModule(module);
                    addModule(module);
                    monitorModule(module);
                }
            }

            @Override
            public void onDeleted(String file) {
                Module module = getModuleById(file);
                if (module != null) {
                    logger.log(Level.INFO, "removing module  : " + module.getName());
                    removeModule(module);
                }
            }

        });
        monitor.watch();
    }

    private void monitorModule(final Module module) {
        FileMonitor monitor = new FileMonitor(module.getFolder());
        monitor.addListener(new FileListener() {

            @Override
            public void onCreated(String file) {
                if (file.equals(MODULE_METADATA)) {
                    updateModule(module);
                } else if (file.endsWith(".jsp") || file.endsWith(".html")) {
                    registerPage(module, file);
                }
            }

            @Override
            public void onDeleted(String file) {

            }

        });
        monitor.watch();
    }

    private void registerPage(Module module, String file) {
        try {
            CachingTilesContainer container = (CachingTilesContainer) TilesAccess.getContainer(servletContext);
            String name = file.endsWith(".jsp") ? file.substring(0, file.length() - 4)
                    : file.substring(0, file.length() - 5);
            Template template = getCurrentTemplate(module);
            Definition definition = createDefinition(module.getUrl() + "/" + name, module.getUrl(),
                    template.getIndexPage());
            definition.putAttribute("content", new Attribute("/modules/" + module.getId() + "/" + file));
            container.register(definition);
        } catch (Exception es) {
            es.printStackTrace();
        }
    }

    private void registerPages(Module module) throws Exception {
        CachingTilesContainer container = (CachingTilesContainer) TilesAccess.getContainer(servletContext);
        Template template = getCurrentTemplate(module);
        Definition definition = createDefinition(module.getUrl(), module.getType(), template.getIndexPage());
        definition.putAttribute("content",
                new Attribute("/modules/" + module.getId() + "/" + module.getIndexPage()));
        container.register(definition);
        for (File file : module.getFolder().listFiles()) {
            String name = file.getName();
            if (file.isFile() && (name.endsWith(".jsp") || name.endsWith(".html"))) {
                String prefix = name.endsWith(".jsp") ? name.substring(0, name.length() - 4)
                        : name.substring(0, name.length() - 5);
                definition = createDefinition(module.getUrl() + "/" + prefix, module.getUrl(),
                        template.getIndexPage());
                definition.putAttribute("content", new Attribute("/modules/" + module.getId() + "/" + name));
                container.register(definition);
            }
        }
    }

    private Template getCurrentTemplate(Module module) {
        TemplateManager templateManager = TemplateManager.getInstance();
        return module.isBackend() ? templateManager.getBackendTemplate(null)
                : templateManager.getFrontendTemplate(null);
    }

    private Definition createDefinition(String name, String parent, String template) {
        Definition definition = new Definition();
        definition.setName(name);
        definition.setExtends(parent);
        definition.setTemplate(template);
        definition.setPreparer("org.metamorphosis.core.PagePreparer");
        return definition;
    }

    public Module getCurrentModule() {
        HttpServletRequest request = ServletActionContext.getRequest();
        String uri = request.getRequestURI();
        String url = uri.substring(request.getContextPath().length() + 1, uri.length());
        url = url.indexOf("/") != -1 ? url.substring(0, url.indexOf("/")) : url;
        Module module = getModuleByUrl(url);
        return module != null ? module : getModuleByUrl("/");
    }

    public Module getModuleByUrl(String url) {
        for (Module module : modules) {
            if (module.getUrl().equals(url) || ("/" + module.getUrl()).equals(url))
                return module;
        }
        return null;
    }

    public Object buildAction(String url) throws Exception {
        Module module = getCurrentModule();
        if (module != null) {
            Action action = module.getAction(url);
            if (action != null && action.getScript() != null) {
                File script = new File(module.getFolder() + "/scripts/" + action.getScript());
                if (script.exists()) {
                    String name = script.getName();
                    String extension = name.substring(name.indexOf(".") + 1);
                    ScriptEngine engine = new ScriptEngineManager().getEngineByExtension(extension);
                    return engine.eval(new FileReader(script));
                }
            }
        }
        return null;
    }

    public Module getModuleById(String id) {
        for (Module module : modules) {
            if (module.getId().equals(id))
                return module;
        }
        return null;
    }

    public void addModule(Module module) {
        module.setIndex(modules.size());
        modules.add(module);
    }

    public void removeModule(Module module) {
        modules.remove(module.getIndex());
        configuration.removePackageConfig(module.getId());
        configuration.rebuildRuntimeConfiguration();
    }

    public void updateModule(Module module) {
        try {
            logger.log(Level.INFO, "updating module  : " + module.getName());
            File folder = module.getFolder();
            int index = module.getIndex();
            String id = module.getId();
            module = parse(new File(folder + "/" + MODULE_METADATA));
            module.setFolder(folder);
            module.setIndex(index);
            initModule(module);
            modules.set(index, module);
            configuration.removePackageConfig(id);
            PackageConfig.Builder packageBuilder = new PackageConfig.Builder(module.getId());
            packageBuilder.namespace("/" + module.getUrl());
            packageBuilder.addParent(configuration.getPackageConfig("root"));
            for (Menu menu : module.getMenus()) {
                for (MenuItem item : menu.getMenuItems()) {
                    if (!item.getUrl().equals(module.getUrl())) {
                        String url = item.getUrl().substring(module.getUrl().length() + 1);
                        ActionConfig.Builder actionBuilder = new ActionConfig.Builder(url, url, null);
                        ResultConfig.Builder resultBuilder = new ResultConfig.Builder("success",
                                "org.apache.struts2.views.tiles.TilesResult");
                        resultBuilder.addParam("location", item.getUrl());
                        actionBuilder.addResultConfig(resultBuilder.build());
                        ActionConfig actionConfig = actionBuilder.build();
                        packageBuilder.addActionConfig(url, actionConfig);
                    }
                }
            }
            for (Action action : module.getActions()) {
                ActionConfig.Builder actionBuilder = new ActionConfig.Builder(action.getUrl(), action.getUrl(),
                        action.getClassName());
                actionBuilder.methodName(action.getMethod());
                for (Result result : action.getResults()) {
                    if (!result.getValue().equals("") && !result.getValue().startsWith("/")) {
                        result.setValue(module.getUrl() + "/" + result.getValue());
                    }
                    String type = result.getType();
                    ResultConfig.Builder resultBuilder = null;
                    if (type.equals("tiles")) {
                        resultBuilder = new ResultConfig.Builder(result.getName(),
                                "org.apache.struts2.views.tiles.TilesResult");
                    } else if (type.equals("redirect")) {
                        resultBuilder = new ResultConfig.Builder(result.getName(),
                                "org.apache.struts2.dispatcher.ServletRedirectResult");
                    } else if (type.equals("redirectAction")) {
                        resultBuilder = new ResultConfig.Builder(result.getName(),
                                "org.apache.struts2.dispatcher.ServletActionRedirectResult");
                    } else if (type.equals("dispatcher")) {
                        resultBuilder = new ResultConfig.Builder(result.getName(),
                                "org.apache.struts2.dispatcher.ServletDispatcherResult");
                    } else if (type.equals("json")) {
                        resultBuilder = new ResultConfig.Builder(result.getName(),
                                "org.apache.struts2.json.JSONResult");
                    }
                    if (resultBuilder != null) {
                        resultBuilder.addParam("location", result.getValue());
                        for (Parameter parameter : result.getParameters()) {
                            resultBuilder.addParam(parameter.getName(), parameter.getValue());
                        }
                        actionBuilder.addResultConfig(resultBuilder.build());
                    }
                }
                ActionConfig actionConfig = actionBuilder.build();
                packageBuilder.addActionConfig(action.getUrl(), actionConfig);
                if (action.getName() != null && action.isGlobal()) {
                    servletContext.setAttribute(action.getName(), module.getUrl() + "/" + action.getUrl());
                }
            }
            PackageConfig packageConfig = packageBuilder.build();
            configuration.addPackageConfig(module.getId(), packageConfig);
            configuration.rebuildRuntimeConfiguration();
            registerPages(module);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public List<Module> getModules() {
        return modules;
    }

    public void setModules(List<Module> modules) {
        this.modules = modules;
    }

    public List<Module> getVisibleModules(String type) {
        List<Module> modules = new ArrayList<Module>();
        for (Module module : this.modules) {
            if (module.isVisible() && module.getType().equals(type))
                modules.add(module);
        }
        return modules;
    }

    public Module getDefaultBackendModule() {
        for (Module module : this.modules) {
            if (module.isBackend())
                return module;
        }
        return null;
    }

    public List<Module> getAdminModules() {
        List<Module> modules = new ArrayList<Module>();
        for (Module module : this.modules) {
            if (module.isAdministrable())
                modules.add(module);
        }
        return modules;
    }

    public Module getMain() {
        for (Module module : modules) {
            if (module.isMain() && module.isBackend())
                return module;
        }
        return getDefaultBackendModule();
    }

    public Configuration getConfiguration() {
        return configuration;
    }

    public void setConfiguration(Configuration configuration) {
        this.configuration = configuration;
    }

    public ServletContext getServletContext() {
        return servletContext;
    }

    public void setServletContext(ServletContext servletContext) {
        this.servletContext = servletContext;
    }

    @Override
    public void dispatcherInitialized(Dispatcher dispatcher) {
        configuration = dispatcher.getConfigurationManager().getConfiguration();
    }

    @Override
    public void dispatcherDestroyed(Dispatcher dispatcher) {
    }

    public static ModuleManager getInstance() {
        return instance;
    }

}