/* vim: set ts=2 et sw=2 cindent fo=qroca: */
package com.globant.katari.core.web;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.EventListener;
import org.apache.commons.lang.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.globant.katari.core.login.LoginConfigurationSetter;
import com.globant.katari.core.login.LoginProvider;
import com.globant.katari.core.security.UrlToRoleMapper;
import com.globant.katari.core.spring.KatariMessageSource;
/** The module context is the way a module interacts with the module container.
*
* Through this class, modules can declare to the container the entry points,
* weblets and menus.
*/
public class ModuleContext {
/** Class logger.
*/
private static Logger log = LoggerFactory.getLogger(ModuleContext.class);
/** Module name.
*
* It is never null.
*/
private final String name;
/** The application ModuleContainerServlet.
*
* It is never null.
*/
private final ModuleContainerServlet containerServlet;
/** The application-wise ModuleListenerProxy.
*
* Modules register their listeners in this proxy. It is never null.
*/
private final ModuleListenerProxy listenerProxy;
/** The application-wise ModuleFilterProxy.
*
* Modules register their filters in this proxy. It is never null.
*/
private final ModuleFilterProxy filterProxy;
/** 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 where the module merges its own menu bar.
*
* This is provided by the container. It can be an empty menu bar or it can
* contain some non-leaf menu nodes. This is used to allow the container to
* define the display order of the non-leaf nodes of a menu. It is never
* null.
*/
private final MenuBar menuBar;
/** Maps a bean name to the url fragmente where the corresponding module is
* mapped.
*
* It is never null.
*/
private final Map<String, String> beanToModuleNames;
/** The list of weblets that the module exposes.
*
* It maps the weblet name to its path. It is never null.
*/
@SuppressWarnings("unused")
private Map<String, String> moduleWeblets = new HashMap<String, String>();
/** A url to role mapper that maps all urls to an authenticated user.
*/
private static final UrlToRoleMapper DEFAULT_MAPPER = new UrlToRoleMapper() {
public String[] getRolesForUrl(final String menuNode) {
return new String[]{"IS_AUTHENTICATED_FULLY"};
}
};
/** Maps urls to the roles that has access to that url.
*
* It is never null. By default, it is defaultMapper, a mapper that expects
* the user to be authenticated.
*/
private UrlToRoleMapper urlToRoleMapper = DEFAULT_MAPPER;
/** The login configurer. */
private final LoginConfigurationSetter loginConfigurer;
/** Builds a ModuleContext.
*
* The module context includes a menu bar. This menu bar is provided by the
* container. It can be an empty menu bar or it can contain some non-leaf
* menu nodes. This is used to allow the container to define the display
* order of the non-leaf nodes of a menu.
*
* @param theModuleName The name of the module. It cannot be null.
*
* @param theListenerProxy The module listener proxy. It cannot be null.
*
* @param theFilterProxy The module filter proxy. It cannot be null.
*
* @param theContainerServlet 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 menu bar where the module merges its own menu bar.
* If null, the menu bar from the module is ignored.
*
* @param theBeanToModuleNames Maps a spring bean name to the url fragment
* that the module is mapped to. It cannot be null.
*
* @param theLoginConfigurer the login configuration. It cannot be null.
*/
ModuleContext(final String theModuleName,
final ModuleListenerProxy theListenerProxy,
final ModuleFilterProxy theFilterProxy,
final ModuleContainerServlet theContainerServlet,
final KatariMessageSource theMessageSource,
final MenuBar theMenuBar,
final Map<String, String> theBeanToModuleNames,
final LoginConfigurationSetter theLoginConfigurer) {
log.trace("Entering ModuleContext");
Validate.notNull(theModuleName, "The module name cannot be null");
Validate.notNull(theListenerProxy, "The module listener proxy cannot"
+ " be null");
Validate.notNull(theFilterProxy, "The module filter proxy cannot"
+ " be null");
Validate.notNull(theContainerServlet, "The module contair servlet cannot"
+ " be null");
Validate.notNull(theMessageSource, "The message source cannot be null");
Validate.notNull(theBeanToModuleNames, "The bean to module names map"
+ " cannot be null");
Validate.notNull(theLoginConfigurer, "The login"
+ "configuration cannot be null");
name = theModuleName;
listenerProxy = theListenerProxy;
filterProxy = theFilterProxy;
containerServlet = theContainerServlet;
messageSource = theMessageSource;
menuBar = theMenuBar;
beanToModuleNames = theBeanToModuleNames;
loginConfigurer = theLoginConfigurer;
log.trace("Leaving ModuleContext");
}
/** Returns the name of the module.
*
* @return the name of the module. It never returns null.
*/
public String getModuleName() {
return name;
}
/** Registers the module entry points in the module container servlet.
*
* @param entryPoints A map of regex that match a url, to the servlet
* responsible to handling the request to that url. It cannot be null.
*/
public void registerEntryPoints(final Map<String, ServletAndParameters>
entryPoints) {
Validate.notNull(entryPoints, "The entry points cannot be null");
containerServlet.addModule(name, entryPoints);
}
/** Registers the module menus in the module container servlet.
*
* The module menu will be added into the context root menu. The context root
* menu represents the application root menu so each module needs to register
* each one of his menus on it and then all module cotext root will be merged
* in the registrar.
*
* This process is skipped if the top level menu bar (the menu bar passed to
* the constructor) is null, effectively ignoring the menu from this module.
*
* @param theMenuBar the menu bar to be registered. It cannot be null.
*/
public void registerMenu(final MenuBar theMenuBar) {
if (menuBar != null) {
Validate.notNull(theMenuBar, "The root menu cannot be null");
menuBar.merge(theMenuBar, beanToModuleNames, "module/" + name);
}
}
/** Registers the weblets exposed by the module.
*
* @param theWeblets A map of the weblets names and its paths. It cannot be
* null.
*
* TODO This is currently unused, because we base the weblet location on a
* url naming convention (/weblet/weblet-name. This is error prone, so we
* should ask the context for the weblets. The naming convention is anyway
* convenient, because we do not want to decorate weblets.
*/
public void registerWeblets(final Map<String, String> theWeblets) {
Validate.notNull(theWeblets, "The weblets cannot be null");
moduleWeblets = theWeblets;
}
/** Registers the listeners exposed by the module.
*
* @param listeners The list of listeners provided by the module. It cannot
* be null.
*/
public void registerListeners(final List<EventListener> listeners) {
Validate.notNull(listeners, "The listeners cannot be null");
listenerProxy.addListeners(listeners);
}
/** Registers the filters exposed by the module.
*
* The filters are called on each matching url in priority order. The
* priority is specified in the FilterMapping of each filter.
*
* @param filters The list of filters provided by the module. It cannot be
* null.
*/
public void registerFilters(final List<FilterMapping> filters) {
Validate.notNull(filters, "The filters cannot be null");
filterProxy.addFilters(filters);
}
/** It registers the <code>UrlToRoleMapper</code>.
*
* @param theUrlToRoleMapper the map of urls to the roles that has access to
* that url. It cannot be null.
*/
public void registerUrlToRoleMapper(
final UrlToRoleMapper theUrlToRoleMapper) {
Validate.notNull(theUrlToRoleMapper, "The UrlToRoleMapper cannot"
+ " be null");
this.urlToRoleMapper = theUrlToRoleMapper;
}
/** It gets the urlToMapper.
*
* @return the urlToRoleMapper. It never returns null.
*/
public UrlToRoleMapper getUrlToRoleMapper() {
return urlToRoleMapper;
}
/** Returns the map that matches the names of the weblets this context exposes
* and its urls.
*
* @return webletMap
*/
/*
public Map<String, String> getWebletMap() {
return moduleWeblets;
}
*/
/** returns the menu bar for this module as it was initialized by the module
* itself.
*
* @return the menu bar for this module.
*/
/*
* public MenuBar getMenuBar() { return menuBar; }
*/
/** Perform any needed validations on the class and adds it to the
* corresponding Set. Neither parameter can be <code>null</code>.
*
* @param targetSet
* The set to add the class to.
* @param clazz
* The class to add
*/
protected void doAdd(final Set<Class<?>> targetSet,
final Class<?> clazz) {
Validate.notNull(clazz, "The class cannot be null");
targetSet.add(clazz);
}
/** Sets the login provider for the application.
*
* There can be only one login provider in the application or you will get
* some unexpected results. This is not explicitly checked.
*
* @param provider the login provider. It cannot be null.
*/
public void setLoginProvider(final LoginProvider provider) {
Validate.notNull(provider, "The provider cannot be null");
loginConfigurer.setLoginConfiguration(provider);
}
/** The application-wise message source.
*
* This message source is used when the module does not specifies its own
* message source.
*
* @return the global message source, never null.
*/
public KatariMessageSource getMessageSource() {
return messageSource;
}
}