/* vim: set ts=2 et sw=2 cindent fo=qroca: */ package com.globant.katari.core.web; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.List; import java.util.LinkedList; import org.apache.commons.lang.Validate; import com.globant.katari.core.login.LoginConfigurationSetter; import com.globant.katari.core.spring.KatariMessageSource; /** This class builds and maintains a ModuleContext registry. * * Right now it just builds new <code>ModuleContext</code>s. */ public class ModuleContextRegistrar { /** The registry information, maps a module name to it's module context. * * It is never null. */ private Map<String, ModuleContext> registry = new HashMap<String, ModuleContext>(); /** A map of bean names to module names. * * This is never null. */ private Map<String, String> beanToModuleName = new HashMap<String, String>(); /** The listener proxy that aggregates the listeners provided by all modules. * * It is never null. */ private ModuleListenerProxy moduleListenerProxy; /** The fiter proxy that aggregates the filters provided by all modules. * * It is never null. */ private ModuleFilterProxy moduleFilterProxy; /** The module container servlet that dispatches requests to the modules. * * It is never null. */ private ModuleContainerServlet moduleContainerServlet; /** The application-wise message source. * * This message source is used when the module does not specifies its own * message source. It cannot be null. */ private KatariMessageSource messageSource; /** The menu bar for the whole application. * * In this node all modules will register his modules */ private MenuBar menuBar = new MenuBar("root", "root"); /** The list of regular expressions that matches module names whose menu bars * will be ignored. * * This is an optional list of strings. If a module name matches a regular * expression in this list, all the menu entries for that module are skipped. * It is never null. */ private List<String> moduleMenusToIgnore = new LinkedList<String>(); /** The login provider. */ private LoginConfigurationSetter loginConfiguration; /** A map of the weblet names tho their entry points, for all modules. * * It is never null. */ // private Map<String, String> webletMap = new HashMap<String, String>(); /** Flag that states if ModuleInitializer has called init and registered all * modules. */ private boolean isInitialized = false; /** Builds a new <code>ModuleContextRegistrar</code>. * * @param theModuleListenerProxy The listener proxy that aggregates all the * listeners provided by the modules. It cannot be null. * * @param theModuleFilterProxy The filter proxy that aggregates all the * filters provided by the modules. It cannot be null. * * @param theModuleContainerServlet The module container servlet. It cannot * be null. * * @param theMessageSource The application-wise message source, to be used * when a module does not specify its own. It cannot be null. * * @param theMenuBar The initial menu bar that will be merged with the * modules. This can be used to set the order of the menu containers. It * cannot be null. * * @param theLoginConfiguration The login configuration. It cannot be null. */ public ModuleContextRegistrar( final ModuleListenerProxy theModuleListenerProxy, final ModuleFilterProxy theModuleFilterProxy, final ModuleContainerServlet theModuleContainerServlet, final KatariMessageSource theMessageSource, final MenuBar theMenuBar, final LoginConfigurationSetter theLoginConfiguration) { Validate.notNull(theModuleListenerProxy, "The module listener proxy cannot" + " be null"); Validate.notNull(theModuleFilterProxy, "The module filter proxy cannot be" + " null"); Validate.notNull(theModuleContainerServlet, "The module container servlet" + " cannot be null"); Validate.notNull(theMessageSource, "The message source cannot be null"); Validate.notNull(theMenuBar, "The menu bar cannot be null"); Validate.notNull(theLoginConfiguration, "The login provider " + "cannot be null"); moduleListenerProxy = theModuleListenerProxy; moduleFilterProxy = theModuleFilterProxy; moduleContainerServlet = theModuleContainerServlet; messageSource = theMessageSource; menuBar = theMenuBar; loginConfiguration = theLoginConfiguration; } /** Sets the list of regular expressions that matches module names whose menu * bars will be ignored. * * This is an optional list of strings. If a module name matches a regular * expression in this list, all the menu entries for that module are skipped. * * @param moduleNames a list of regular expresions. It cannot be null. */ public void setModuleMenusToIgnore(final List<String> moduleNames) { Validate.notNull(moduleNames, "The module names cannot be null"); moduleMenusToIgnore = moduleNames; } /** Builds a new <code>ModuleContext</code>. * * @param moduleName The name of the module to build the context for. It * cannot be null. * * @return a module context for the provided module name. It never returns * null. */ public ModuleContext getNewModuleContext(final String moduleName) { Validate.notNull(moduleName, "The module name cannot be null"); ModuleContext context; boolean skipModule = false; for (String ignored : moduleMenusToIgnore) { if (moduleName.matches("^" + ignored + "$")) { skipModule = true; break; } } if (skipModule) { context = new ModuleContext(moduleName, moduleListenerProxy, moduleFilterProxy, moduleContainerServlet, messageSource, null, beanToModuleName, loginConfiguration); } else { context = new ModuleContext(moduleName, moduleListenerProxy, moduleFilterProxy, moduleContainerServlet, messageSource, menuBar, beanToModuleName, loginConfiguration); } registry.put(moduleName, context); return context; } /** Registers a module base name. * * @param beanName The name of the spring bean that defines the module. It * cannot be null. * * @param moduleName The name of the module. */ void addModuleName(final String beanName, final String moduleName) { Validate.notNull(beanName, "The bean name cannot be null"); Validate.notNull(moduleName, "The module name cannot be null"); beanToModuleName.put(beanName, moduleName); } /** Forwards a request to a weblet and renders the output to the response. * * @param moduleName The name of the module. It cannot be null. * * @param webletName The name of the weblet. It cannot be null. * * @param theRequest The original request. It cannot be null. * * @param theResponse The response where the weblet will render the output. * It cannot be null. * * @throws IOException in case of an io error. * * @throws ServletException in case of an unexpected error. */ /* public void getWebletResponse(final String moduleName, final String webletName, final HttpServletRequest theRequest, final HttpServletResponse theResponse) throws IOException, ServletException { Validate.notNull(moduleName, "The module name cannot be null"); Validate.notNull(webletName, "The weblet name cannot be null"); Validate.notNull(theRequest, "The request cannot be null"); Validate.notNull(theResponse, "The response cannot be null"); // ModuleContext context = registry.get(moduleName); // context.getWebletResponse(webletName, theRequest, theResponse); } */ /** Return the application menu in the form of his menu bar. * * @return the application menu in the form of his menu bar. */ public MenuBar getMenuBar() { return this.menuBar; } /** * Returns a Set with the registered module names or an empty set if no * modules were registered. * @return A set with the names of the modules or an empty Set. Never * <code>null</code>. */ public Set<String> getModuleNames() { return registry.keySet(); } /** * Returns the {@link ModuleContext} for the given module name. * @param moduleName * The name of the module, cannot be <code>null</code>. * @return Returns the corresponding {@link ModuleContext} or * <code>null</code> if the module does not exist. */ public ModuleContext getModuleContext(final String moduleName) { Validate.notNull(moduleName, "The module name cannot be null"); return registry.get(moduleName); } /** * Returns the bean names (as registered in Spring) of the registered * modules. * @return A set of modules or an empty set. Never <code>null</code>. */ public Set<String> getModuleBeanNames() { return beanToModuleName.keySet(); } /** Called by ModuleInitializer after it initialized the modules. * * This is a really nasty hack. We two initialization cases: with hibernate * and without hibernate. So we have two initializers: ModuleInitializer and * HibernateInitializer. The problem is that there is no way to define the * order that spring triggers the refresh event, and the HibernateInitializer * needs to be run after ModuleInitializer. So we make HibernateInitializer * extend ModuleInitializer and make ModuleInitializer check if it has * already been called. */ public void setInitialized() { isInitialized = true; } /** Returns if the ModuleInitializer has already registered the modules. * * See setModulesRegistered for the rationale of this operation. * * @return true if the modules has been registered. */ public boolean isInitialized() { return isInitialized; } }