[b]DisplayerMapping[/b]
[b]AbstractDisplayer.java[/b]
/*
* MenuDisplayerMapping.java
*
* Created on February 6, 2001, 5:24 PM
*/
package net.sf.navigator.displayer;
import java.io.Serializable;
/**
*
* @author ssayles
* @version
*/
public class MenuDisplayerMapping implements Serializable {
//~ Instance fields ========================================================
/** Holds value of property name. */
private String name;
/** Holds value of property type. */
private String type;
/** Holds value of property config. */
private String config;
//~ Methods ================================================================
/** Getter for property name.
* @return Value of property name.
*/
public String getName() {
return name;
}
/** Setter for property name.
* @param name New value of property name.
*/
public void setName(String name) {
this.name = name;
}
/** Getter for property type.
* @return Value of property type.
*/
public String getType() {
return type;
}
/** Setter for property type.
* @param type New value of property type.
*/
public void setType(String type) {
this.type = type;
}
/** Getter for property config.
* @return Value of property config.
*/
public String getConfig() {
return config;
}
/** Setter for property config.
* @param config New value of property config.
*/
public void setConfig(String config) {
this.config = config;
}
}
[b]AbstractDisplayer.java[/b]
/*
* AbstractMenuDisplayer.java
*
* Created on March 30, 2002, 3:34 PM
*/
package net.sf.navigator.displayer;
import net.sf.navigator.menu.MenuComponent;
import net.sf.navigator.menu.PermissionsAdapter;
import net.sf.navigator.util.MessageResources;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import java.io.IOException;
/**
* Abstract implementation of <code>MenuDisplayer</code> that can be used as
* a basis for other menu displayers.
*
* @author ssayles
* @version
*/
public abstract class AbstractMenuDisplayer implements MenuDisplayer {
//~ Instance fields ========================================================
protected final transient Log log = LogFactory.getLog(getClass());
protected String name;
protected MessageResources displayStrings;
protected JspWriter out;
protected String target;
/** Holds value of property permissionsAdapter. */
protected PermissionsAdapter permissionsAdapter;
protected MenuDisplayerMapping mapping;
//~ Methods ================================================================
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getConfig() {
String config = null;
if (displayStrings != null) {
config = displayStrings.getConfig();
}
return config;
}
public void setConfig(String config) {
displayStrings = MessageResources.getMessageResources(config);
}
public String getTarget() {
return target;
}
/**
* Convenience method that will first return the target for the displayer
* if it is not null. If the displayer target is null, then it will
* return <code>menu.getTarget()</code>.
*
* @return the target for the menu link.
*/
protected String getTarget(MenuComponent menu) {
String theTarget = null;
if (target == null) {
if (menu.getTarget() != null) {
theTarget = menu.getTarget();
}
} else {
theTarget = target;
}
return theTarget;
}
public void setTarget(String target) {
this.target = target;
}
/**
* Getter for property permissionsAdapter.
* @return Value of property permissionsAdapter.
*/
public PermissionsAdapter getPermissionsAdapter() {
return this.permissionsAdapter;
}
/**
* Setter for property permissionsAdapter.
* @param permissionsAdapter New value of property permissionsAdapter.
*/
public void setPermissionsAdapter(PermissionsAdapter permissionsAdapter) {
this.permissionsAdapter = permissionsAdapter;
}
/**
* Lifecycle method that should be called when the <code>MenuDisplayer</code>
* is being prepared for use.
*
* @param pageContext The JSP pageContext to give the displayer access
* to any resources it may need.
* @param mapping The menu displayer mapping used to embody the xml
* definition.
*/
public void init(PageContext pageContext, MenuDisplayerMapping mapping) {
this.out = pageContext.getOut();
this.mapping = mapping;
}
public abstract void display(MenuComponent menu)
throws JspException, IOException;
public void end(PageContext pageContext) {}
/**
* Returns <code>true</code> if the specified component is usable.
* If <code>permissionsAdapter</code> is not defined, this method will
* return <code>true</code>. Otherwise, the adapter will be used to check
* permissions on the menu.
*
* @return <code>true</code> if the menu component is usable.
* @param menu The menu component.
*/
public boolean isAllowed(MenuComponent menu) {
return permissionsAdapter == null || permissionsAdapter.isAllowed(menu);
}
}
package net.sf.navigator.menu;
/**
* @author DEPeart
*
*/
public interface Component {
String getName();
void setName(String name);
}
package net.sf.navigator.menu;
/**
*
* @author ssayles
* @author mraible
* @version
*/
public abstract class MenuBase implements Component {
//~ Instance fields ========================================================
/** Holds value of property action, that is, Struts Logical Action Name. */
protected String action;
/** Align menu 'left','right','top','bottom' ...and other alignment of particular menu system */
protected String align;
/** Holds value of property altImage. */
protected String altImage;
/** Holds value of property description. */
protected String description;
/** Holds value of property forward. */
protected String forward;
/** Holds value of property height. */
protected String height;
/** Holds value of property image. */
protected String image;
/** Holds value of property location. */
protected String location;
/** Holds value of property name. */
protected String name;
/** Holds value of property onclick. */
protected String onclick;
/** Holds value of property ondblclick. */
protected String ondblclick;
/** Holds value of property onmouseout. */
protected String onmouseout;
/** Holds value of property onmouseover. */
protected String onmouseover;
/** Holds value of property page. */
protected String page;
/** Holds value of property roles. */
protected String roles;
/** Holds value of property target. */
protected String target;
/** Holds value of property title. */
protected String title;
/** Holds value of property toolTip. */
protected String toolTip;
/** Holds value of property width. */
protected String width;
/** Holds parsed (with variables) url that is used to render a link */
private String url;
/** Holds value of property onContextMenu */
protected String onContextMenu;
/**
* Holds value of property module; a Struts module prefix that overrides the current module.
*
* <p>The default module is specified by <code>""</code>. Any non-default module should begin with <code>"/"</code>.
*/
protected String module;
//~ Methods ================================================================
/**
* Sets the value for action.
* @param action New value of property action.
*/
public void setAction(String action) {
this.action = action;
}
/**
* Returns the value for action.
* @return Value of property action.
*/
public String getAction() {
return this.action;
}
/**
* Returns the value for align.
* @return Value of property align.
*/
public String getAlign() {
return align;
}
/**
* Sets the value for align.
* @param align New value of property align.
*/
public void setAlign(String align) {
this.align = align;
}
/** Setter for property altImage.
* @param altImage New value of property altImage.
*/
public void setAltImage(String altImage) {
this.altImage = altImage;
}
/** Getter for property altImage.
* @return Value of property altImage.
*/
public String getAltImage() {
return altImage;
}
/** Setter for property description.
* @param description New value of property description.
*/
public void setDescription(String description) {
this.description = description;
}
/** Getter for property description.
* @return Value of property description.
*/
public String getDescription() {
return description;
}
/**
* Sets the forward.
* @param forward The forward to set
*/
public void setForward(String forward) {
this.forward = forward;
}
/**
* @return String
*/
public String getForward() {
return forward;
}
/**
* @param height
*/
public void setHeight(String height) {
this.height = height;
}
/**
* @return
*/
public String getHeight() {
return height;
}
/** Setter for property image.
* @param image New value of property image.
*/
public void setImage(String image) {
this.image = image;
}
/** Getter for property image.
* @return Value of property image.
*/
public String getImage() {
return image;
}
/** Setter for property location.
* @param location New value of property location.
*/
public void setLocation(String location) {
this.location = location;
}
/** Getter for property location.
* @return Value of property location.
*/
public String getLocation() {
return location;
}
/** Setter for property name.
* @param name New value of property name.
*/
public void setName(String name) {
this.name = name;
}
/** Getter for property name.
* @return Value of property name.
*/
public String getName() {
return name;
}
/** Setter for property onclick.
* @param onclick New value of property onclick.
*/
public void setOnclick(String onclick) {
this.onclick = onclick;
}
/** Getter for property onclick.
* @return Value of property onclick.
*/
public String getOnclick() {
return onclick;
}
/** Setter for property onmouseout.
* @param onmouseout New value of property onmouseout.
*/
public void setOnmouseout(String onmouseout) {
this.onmouseout = onmouseout;
}
/** Getter for property onmouseout.
* @return Value of property onmouseout.
*/
public String getOnmouseout() {
return onmouseout;
}
/** Setter for property onmouseover.
* @param onmouseover New value of property onmouseover.
*/
public void setOnmouseover(String onmouseover) {
this.onmouseover = onmouseover;
}
/** Getter for property onmouseover.
* @return Value of property onmouseover.
*/
public String getOnmouseover() {
return onmouseover;
}
/**
* Sets the value for page.
* @param page New value of property page.
*/
public void setPage(String page) {
this.page = page;
}
/**
* Returns the value for page.
* @return Value of property page.
*/
public String getPage() {
return this.page;
}
/**
* Sets the roles.
* @param roles The roles to set
*/
public void setRoles(String roles) {
this.roles = roles;
}
/**
* Returns the roles.
* @return String
*/
public String getRoles() {
return roles;
}
/** Setter for property target.
* @param target New value of property target.
*/
public void setTarget(String target) {
this.target = target;
}
/** Getter for property target.
* @return Value of property target.
*/
public String getTarget() {
return target;
}
/** Setter for property title.
* @param title New value of property title.
*/
public void setTitle(String title) {
this.title = title;
}
/** Getter for property title.
* @return Value of property title.
*/
public String getTitle() {
return title;
}
/** Setter for property toolTip.
* @param toolTip New value of property toolTip.
*/
public void setToolTip(String toolTip) {
this.toolTip = toolTip;
}
/** Getter for property toolTip.
* @return Value of property toolTip.
*/
public String getToolTip() {
return toolTip;
}
/**
* @param url
*/
public void setUrl(String url) {
this.url = url;
}
/**
* @return
*/
public String getUrl() {
return url;
}
/**
* Sets the width.
* @param width The width to set
*/
public void setWidth(String width) {
this.width = width;
}
/**
* @return String
*/
public String getWidth() {
return width;
}
/**
* @return
*/
public String getOnContextMenu() {
return onContextMenu;
}
/**
* @param string
*/
public void setOnContextMenu(String string) {
onContextMenu = string;
}
/**
* Returns the ondblclick.
* @return String
*/
public String getOndblclick() {
return ondblclick;
}
/**
* Sets the ondblclick.
* @param ondblclick The ondblclick to set
*/
public void setOndblclick(String ondblclick) {
this.ondblclick = ondblclick;
}
public String getModule() {
return module;
}
public void setModule(String module) {
this.module = module;
}
}
/*
* MenuComponent.java
*
* Created on January 28, 2001, 8:10 PM
*/
package net.sf.navigator.menu;
import org.apache.commons.lang.StringUtils;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
/**
* This class extends {@link MenuBase} and basically contains helper methods
* for adding and fetching children and parents.
*
* @author Scott Sayles, Matt Raible
* @version $Revision: 1.19 $ $Date: 2006/10/17 11:27:09 $
*/
public class MenuComponent extends MenuBase implements Serializable, Component {
//~ Static fields/initializers =============================================
protected static MenuComponent[] _menuComponent = new MenuComponent[0];
//~ Instance fields ========================================================
protected List menuComponents = Collections.synchronizedList(new ArrayList());
protected MenuComponent parentMenu;
private boolean last;
private String breadCrumb;
//~ Methods ================================================================
public void addMenuComponent(MenuComponent menuComponent) {
if ((menuComponent.getName() == null) || (menuComponent.getName().equals(""))) {
menuComponent.setName(this.name + menuComponents.size());
}
if (!menuComponents.contains(menuComponent)) {
menuComponents.add(menuComponent);
menuComponent.setParent(this);
}
}
public MenuComponent[] getMenuComponents() {
return (MenuComponent[]) menuComponents.toArray(_menuComponent);
}
public void setMenuComponents(MenuComponent[] menuComponents) {
for (int i = 0; i < menuComponents.length; i++) {
MenuComponent component = menuComponents[i];
this.menuComponents.add(component);
}
}
public void setParent(MenuComponent parentMenu) {
if (parentMenu != null) {
// look up the parent and make sure that it has this menu as a child
if (!parentMenu.getComponents().contains(this)) {
parentMenu.addMenuComponent(this);
}
}
this.parentMenu = parentMenu;
}
public MenuComponent getParent() {
return parentMenu;
}
/**
* Convenience method for Velocity templates
* @return menuComponents as a java.util.List
*/
public List getComponents() {
return menuComponents;
}
/**
* This method compares all attributes, except for parent and children
*
* @param o the object to compare to
*/
public boolean equals(Object o) {
if (!(o instanceof MenuComponent)) {
return false;
}
MenuComponent m = (MenuComponent) o;
// Compare using StringUtils to avoid NullPointerExceptions
return StringUtils.equals(m.getAction(), this.action) &&
StringUtils.equals(m.getAlign(), this.align) &&
StringUtils.equals(m.getAltImage(), this.altImage) &&
StringUtils.equals(m.getDescription(), this.description) &&
StringUtils.equals(m.getForward(), this.forward) &&
StringUtils.equals(m.getHeight(), this.height) &&
StringUtils.equals(m.getImage(), this.image) &&
StringUtils.equals(m.getLocation(), this.location) &&
StringUtils.equals(m.getName(), this.name) &&
StringUtils.equals(m.getOnclick(), this.onclick) &&
StringUtils.equals(m.getOndblclick(), this.ondblclick) &&
StringUtils.equals(m.getOnmouseout(), this.onmouseout) &&
StringUtils.equals(m.getOnmouseover(), this.onmouseover) &&
StringUtils.equals(m.getOnContextMenu(), this.onContextMenu) &&
StringUtils.equals(m.getPage(), this.page) &&
StringUtils.equals(m.getRoles(), this.roles) &&
StringUtils.equals(m.getTarget(), this.target) &&
StringUtils.equals(m.getTitle(), this.title) &&
StringUtils.equals(m.getToolTip(), this.toolTip) &&
StringUtils.equals(m.getWidth(), this.width) &&
StringUtils.equals(m.getModule(), this.module);
}
/**
* Get the depth of the menu
*
* @return Depth of menu
*/
public int getMenuDepth() {
return getMenuDepth(this, 0);
}
private int getMenuDepth(MenuComponent menu, int currentDepth) {
int depth = currentDepth + 1;
MenuComponent[] subMenus = menu.getMenuComponents();
if (subMenus != null) {
for (int a = 0; a < subMenus.length; a++) {
int depthx = getMenuDepth(subMenus[a], currentDepth + 1);
if (depth < depthx)
depth = depthx;
}
}
return depth;
}
/**
* Returns the last.
*
* @return boolean
*/
public boolean isLast() {
return last;
}
/**
* Sets the last.
*
* @param last The last to set
*/
public void setLast(boolean last) {
this.last = last;
}
/**
* Remove all children from a parent menu item
*/
public void removeChildren() {
for (Iterator iterator = this.getComponents().iterator(); iterator.hasNext();) {
MenuComponent child = (MenuComponent) iterator.next();
child.setParent(null);
iterator.remove();
}
}
public String getBreadCrumb() {
return breadCrumb;
}
/**
* Build the breadcrumb trail leading to this menuComponent
*
* @param delimiter type of separator
*/
protected void setBreadCrumb(String delimiter) {
if (getParent() == null) {
breadCrumb = name;
setChildBreadCrumb(delimiter);
} else {
MenuComponent parent = getParent();
breadCrumb = parent.getBreadCrumb() + delimiter + name;
setChildBreadCrumb(delimiter);
}
}
private void setChildBreadCrumb(String delimiter) {
List children = this.getComponents();
for (Iterator iterator = children.iterator(); iterator.hasNext();) {
MenuComponent child = (MenuComponent) iterator.next();
child.setBreadCrumb(delimiter);
}
}
public String toString() {
return "name: " + this.name;
}
}
package net.sf.navigator.menu;
import net.sf.navigator.util.LoadableResourceException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* This class is designed for use in applications that don't use Struts
* but do want to use Struts Menu. You simply need to configure this
* listener in your web.xml file with the following syntax:</p>
* <pre>
* <!--
* - Loads the menu-config.xml for struts-menu at startup,
* - by default from "/WEB-INF/menu-config.xml".
* - To override this, add a context-param named "menuConfigLocation"
* - web.xml file.
* -->
* <listener>
* <listener-class>net.sf.navigator.menu.MenuContextListener</listener-class>
* </listener>
* </pre>
*
* @author Matt Raible
*/
public class MenuContextListener implements ServletContextListener {
private static Log log = LogFactory.getLog(MenuContextListener.class);
private ServletContext ctx;
/** Configuration file for menus */
private String menuConfig = "/WEB-INF/menu-config.xml";
/**
* Initialization of the Menu Repository.
*/
public void contextInitialized(ServletContextEvent sce) {
ctx = sce.getServletContext();
if (log.isDebugEnabled()) {
log.debug("Starting struts-menu initialization");
}
// check for menuConfigLocation context-param
String override =
sce.getServletContext().getInitParameter("menuConfigLocation");
if (override != null) {
if (log.isDebugEnabled()) {
log.debug("using menuConfigLocation: " + override);
}
this.menuConfig = override;
}
MenuRepository repository = new MenuRepository();
repository.setLoadParam(menuConfig);
repository.setServletContext(ctx);
try {
repository.load();
ctx.setAttribute(MenuRepository.MENU_REPOSITORY_KEY, repository);
if (log.isDebugEnabled()) {
log.debug("struts-menu initialization successfull");
}
} catch (LoadableResourceException lre) {
log.fatal("Failure initializing struts-menu: " + lre.getMessage());
}
}
public void contextDestroyed(ServletContextEvent sce) {
if (log.isDebugEnabled()) {
log.debug("destroying struts-menu...");
}
sce.getServletContext().removeAttribute(MenuRepository.MENU_REPOSITORY_KEY);
menuConfig = null;
ctx = null;
}
}
package net.sf.navigator.menu;
import net.sf.navigator.util.LoadableResourceException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContextException;
import org.springframework.web.context.support.WebApplicationObjectSupport;
import javax.servlet.ServletException;
/**
* This loader is available for those that use the Spring Framework. To
* use it, simply configure it as follows in your applicationContext.xml file.
* </p>
* <pre>
* <bean id="menu" class="net.sf.navigator.menu.MenuLoader">
* <property name="menuConfig">
* <value>/WEB-INF/menu-config.xml</value>
* </property>
* </bean>
* </pre>
* <p>The menuConfig property is an optional attribute. It is set to
* /WEB-INF/menu-config.xml by default.</p>
*
* @author Matt Raible
*/
public class MenuLoader extends WebApplicationObjectSupport {
private static Log log = LogFactory.getLog(MenuLoader.class);
/** Configuration file for menus */
private String menuConfig = "/WEB-INF/menu-config.xml";
/**
* Set the Menu configuration file
* @param menuConfig the file containing the Menus/Items
*/
public void setMenuConfig(String menuConfig) {
this.menuConfig = menuConfig;
}
/**
* Initialization of the Menu Repository.
* @throws org.springframework.context.ApplicationContextException if an error occurs
*/
protected void initApplicationContext() throws ApplicationContextException {
try {
if (log.isDebugEnabled()) {
log.debug("Starting struts-menu initialization");
}
MenuRepository repository = new MenuRepository();
repository.setLoadParam(menuConfig);
repository.setServletContext(getServletContext());
try {
repository.load();
getServletContext().setAttribute(MenuRepository.MENU_REPOSITORY_KEY, repository);
if (log.isDebugEnabled()) {
log.debug("struts-menu initialization successful");
}
} catch (LoadableResourceException lre) {
throw new ServletException("Failure initializing struts-menu: " +
lre.getMessage());
}
} catch (Exception ex) {
throw new ApplicationContextException("Failed to initialize Struts Menu repository",
ex);
}
}
}
/*
* MenuPlugin.java
*
* Created on March 6, 2002, 10:04 PM
*/
package net.sf.navigator.menu;
import net.sf.navigator.util.LoadableResourceException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.action.ActionServlet;
import org.apache.struts.action.PlugIn;
import org.apache.struts.config.ModuleConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
/**
* Struts plug-in adapter for the menuing module.
*
* @author ssayles
*/
public class MenuPlugIn implements PlugIn {
//~ Instance fields ========================================================
/**
* The <code>Log</code> instance for this class.
*/
private static Log log = LogFactory.getLog(MenuPlugIn.class);
private MenuRepository repository;
private String menuConfig = "/WEB-INF/menu-config.xml";
private HttpServlet servlet;
//~ Methods ================================================================
public String getMenuConfig() {
return menuConfig;
}
public void setMenuConfig(String menuConfig) {
this.menuConfig = menuConfig;
}
public void init(ActionServlet servlet, ModuleConfig config)
throws ServletException {
if (log.isDebugEnabled()) {
log.debug("Starting struts-menu initialization");
}
this.servlet = servlet;
repository = new MenuRepository();
repository.setLoadParam(menuConfig);
repository.setServletContext(servlet.getServletContext());
try {
repository.load();
servlet.getServletContext().setAttribute(MenuRepository.MENU_REPOSITORY_KEY, repository);
if (log.isDebugEnabled()) {
log.debug("struts-menu initialization successful");
}
} catch (LoadableResourceException lre) {
throw new ServletException("Failure initializing struts-menu: " +
lre.getMessage());
}
}
public void destroy() {
repository = null;
servlet.getServletContext().removeAttribute(MenuRepository.MENU_REPOSITORY_KEY);
menuConfig = null;
servlet = null;
}
}
/*
* MenuRepository.java
*
* Created on January 29, 2001, 9:51 AM
*/
package net.sf.navigator.menu;
import net.sf.navigator.displayer.MenuDisplayerMapping;
import net.sf.navigator.displayer.VelocityMenuDisplayer;
import net.sf.navigator.util.LoadableResource;
import net.sf.navigator.util.LoadableResourceException;
import org.apache.commons.collections.map.LinkedMap;
import org.apache.commons.digester.Digester;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.servlet.ServletContext;
import java.io.InputStream;
import java.io.Serializable;
import java.util.*;
/**
* Holder of Menus and their items. Can be populated programmatically.
*
* @author ssayles, mraible
*/
public class MenuRepository implements LoadableResource, Serializable {
//~ Static fields/initializers =============================================
public static final String MENU_REPOSITORY_KEY = "net.sf.navigator.menu.MENU_REPOSITORY";
private static Log log = LogFactory.getLog(MenuRepository.class);
//~ Instance fields ========================================================
protected String config = null;
protected String name = null;
protected ServletContext servletContext = null;
protected LinkedMap menus = new LinkedMap();
protected LinkedMap displayers = new LinkedMap();
protected LinkedMap templates = new LinkedMap();
private String breadCrumbDelimiter;
//~ Methods ================================================================
public Set getMenuNames() {
return menus.keySet();
}
/**
* Convenience method for dynamic menus - returns the top-level menus
* only.
*/
public List getTopMenus() {
List topMenus = new ArrayList();
if (menus == null) {
log.warn("No menus found in repository!");
return topMenus;
}
for (Iterator it = menus.keySet().iterator(); it.hasNext();) {
String name = (String) it.next();
MenuComponent menu = getMenu(name);
if (menu.getParent() == null) {
topMenus.add(menu);
}
}
return topMenus;
}
public MenuComponent getMenu(String menuName) {
return (MenuComponent) menus.get(menuName);
}
public MenuDisplayerMapping getMenuDisplayerMapping(String displayerName) {
return (MenuDisplayerMapping) displayers.get(displayerName);
}
protected Digester initDigester() {
Digester digester = new Digester();
digester.setClassLoader(Thread.currentThread().getContextClassLoader());
digester.push(this);
//digester.setDebug(getDebug());
// 1
digester.addObjectCreate("MenuConfig/Menus/Menu", "net.sf.navigator.menu.MenuComponent", "type");
digester.addSetProperties("MenuConfig/Menus/Menu");
digester.addSetNext("MenuConfig/Menus/Menu", "addMenu");
// 2
digester.addObjectCreate("MenuConfig/Menus/Menu/Item", "net.sf.navigator.menu.MenuComponent", "type");
digester.addSetProperties("MenuConfig/Menus/Menu/Item");
digester.addSetNext("MenuConfig/Menus/Menu/Item", "addMenuComponent", "net.sf.navigator.menu.MenuComponent");
// 3
digester.addObjectCreate("MenuConfig/Menus/Menu/Item/Item", "net.sf.navigator.menu.MenuComponent", "type");
digester.addSetProperties("MenuConfig/Menus/Menu/Item/Item");
digester.addSetNext("MenuConfig/Menus/Menu/Item/Item", "addMenuComponent", "net.sf.navigator.menu.MenuComponent");
// 4
digester.addObjectCreate("MenuConfig/Menus/Menu/Item/Item/Item", "net.sf.navigator.menu.MenuComponent", "type");
digester.addSetProperties("MenuConfig/Menus/Menu/Item/Item/Item");
digester.addSetNext("MenuConfig/Menus/Menu/Item/Item/Item", "addMenuComponent", "net.sf.navigator.menu.MenuComponent");
// 5
digester.addObjectCreate("MenuConfig/Menus/Menu/Item/Item/Item/Item", "net.sf.navigator.menu.MenuComponent", "type");
digester.addSetProperties("MenuConfig/Menus/Menu/Item/Item/Item/Item");
digester.addSetNext("MenuConfig/Menus/Menu/Item/Item/Item/Item", "addMenuComponent", "net.sf.navigator.menu.MenuComponent");
// 6
digester.addObjectCreate("MenuConfig/Menus/Menu/Item/Item/Item/Item/Item", "net.sf.navigator.menu.MenuComponent", "type");
digester.addSetProperties("MenuConfig/Menus/Menu/Item/Item/Item/Item/Item");
digester.addSetNext("MenuConfig/Menus/Menu/Item/Item/Item/Item/Item", "addMenuComponent", "net.sf.navigator.menu.MenuComponent");
// 7
digester.addObjectCreate("MenuConfig/Menus/Menu/Item/Item/Item/Item/Item/Item", "net.sf.navigator.menu.MenuComponent", "type");
digester.addSetProperties("MenuConfig/Menus/Menu/Item/Item/Item/Item/Item/Item");
digester.addSetNext("MenuConfig/Menus/Menu/Item/Item/Item/Item/Item/Item", "addMenuComponent", "net.sf.navigator.menu.MenuComponent");
digester.addObjectCreate("MenuConfig/Displayers/Displayer", "net.sf.navigator.displayer.MenuDisplayerMapping", "mapping");
digester.addSetProperties("MenuConfig/Displayers/Displayer");
digester.addSetNext("MenuConfig/Displayers/Displayer", "addMenuDisplayerMapping", "net.sf.navigator.displayer.MenuDisplayerMapping");
digester.addSetProperty("MenuConfig/Displayers/Displayer/SetProperty", "property", "value");
return digester;
}
/**
* Adds a new menu. This is called when parsing the menu xml definition.
* @param menu The menu component to add.
*/
public void addMenu(MenuComponent menu) {
if (menus.containsKey(menu.getName())) {
if (log.isDebugEnabled()) {
log.warn("Menu '" + menu.getName() + "' already exists in repository");
}
List children = (getMenu(menu.getName())).getComponents();
if (children != null && menu.getComponents() != null) {
for (Iterator it = children.iterator(); it.hasNext();) {
MenuComponent child = (MenuComponent) it.next();
menu.addMenuComponent(child);
}
}
}
menus.put(menu.getName(), menu);
}
/**
* Allows easy removal of a menu by its name.
* @param name
*/
public void removeMenu(String name) {
menus.remove(name);
}
/**
* Allows easy removal of all menus, suggested use for users wanting to reload menus without having to perform
* a complete reload of the MenuRepository
*/
public void removeAllMenus() {
menus.clear();
}
public void addMenuDisplayerMapping(MenuDisplayerMapping displayerMapping) {
displayers.put(displayerMapping.getName(), displayerMapping);
if (displayerMapping.getType().equals("net.sf.navigator.displayer.VelocityMenuDisplayer")) {
if (servletContext == null) {
log.error("ServletContext not set - can't initialize Velocity");
} else {
VelocityMenuDisplayer.initialize(servletContext);
}
}
}
/**
* This method is so menu repositories can retrieve displayers from the
* default repository specified in menu-config.xml
* @return the displayers specified in this repository
*/
public LinkedMap getDisplayers() {
return displayers;
}
/**
* Allow the displayers to be set as a whole. This should only be used
* when copying the displayers from the default repository to a newly
* created repository.
* @param displayers
*/
public void setDisplayers(LinkedMap displayers) {
this.displayers = displayers;
}
public void load() throws LoadableResourceException {
if (getServletContext() == null) {
throw new LoadableResourceException("no reference to servlet context found");
}
InputStream input = null;
Digester digester = initDigester();
try {
input = getServletContext().getResourceAsStream(config);
digester.parse(input);
} catch (Exception e) {
e.printStackTrace();
throw new LoadableResourceException("Error parsing resource file: " + config + " nested exception is: " + e.getMessage());
} finally {
try {
input.close();
} catch (Exception e) {
}
}
}
public void reload() throws LoadableResourceException {
menus.clear();
displayers.clear();
load();
}
public void setLoadParam(String loadParam) {
config = loadParam;
}
public String getLoadParam() {
return config;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public ServletContext getServletContext() {
return servletContext;
}
public void setServletContext(ServletContext context) {
this.servletContext = context;
}
/**
* Method getMenu. Get a subMenu beneath a root or parent menu. Will drill-down as deep as requested
* @param menuName - e.g grandParent.parent.menu
* @param delimiter - e.g. '.'
* @return MenuComponent
*/
public MenuComponent getMenu(String menuName, String delimiter) {
MenuComponent parent = null;
StringTokenizer st = new StringTokenizer(menuName, delimiter);
boolean firstMenu = true;
while (st.hasMoreTokens()) {
if (firstMenu) {
parent = this.getMenu(st.nextToken());
firstMenu = false;
} else {
MenuComponent child = null;
String name = st.nextToken();
for (int a = 0; a < parent.getComponents().size(); a++) {
if (name.equals(((MenuComponent) parent.getComponents().get(a)).getName())) {
child = (MenuComponent) parent.getComponents().get(a);
a = parent.getComponents().size();
}
}
if (child != null) {
parent = child;
} else {
parent = null;
break;
}
}
}
return parent;
}
/**
* Method getMenuDepth.
* Get the depth of the deepest sub-menu within the requested top menu
* @param menuName - name of the top menu to check the menu depth
* @return int. If no menuName found return -1
*/
public int getMenuDepth(String menuName) {
MenuComponent menu = this.getMenu(menuName);
if (menu == null)
return -1;
if (menu.getMenuComponents() == null)
return 1;
return menu.getMenuDepth();
}
/**
* Method getMenuDepth.
* Get the depth of the deepest sub-menu throughout all menus held in the repository
* @return int. If no menus return -1.
*/
public int getMenuDepth() {
int currentDepth = 0;
List topMenus = this.getTopMenus();
if (topMenus == null)
return -1;
for (Iterator menu = topMenus.iterator(); menu.hasNext();) {
int depth = ((MenuComponent) menu.next()).getMenuDepth();
if (currentDepth < depth)
currentDepth = depth;
}
return currentDepth;
}
/**
* Method getTopMenusAsArray. Get menus as array rather than a List
* @return MenuComponent[]
*/
public MenuComponent[] getTopMenusAsArray() {
List menuList = this.getTopMenus();
MenuComponent[] menus = new MenuComponent[menuList.size()];
for (int a = 0; a < menuList.size(); a++) {
menus[a] = (MenuComponent) menuList.get(a);
}
return menus;
}
/**
* Get a List of all the top menus' names
* @return List
*/
public List getTopMenusNames() {
List menus = this.getTopMenus();
ArrayList names = new ArrayList();
for (Iterator iterator = menus.iterator(); iterator.hasNext();) {
MenuComponent menu = (MenuComponent) iterator.next();
names.add(menu.getName());
}
return names;
}
public void setBreadCrumbDelimiter(String string) {
breadCrumbDelimiter = string;
}
public void buildBreadCrumbs() {
if (breadCrumbDelimiter == null) {
throw new NullPointerException("No breadCrumbDelimiter present");
}
ArrayList menus = (ArrayList)this.getTopMenus();
for (Iterator iterator = menus.iterator(); iterator.hasNext();) {
MenuComponent menu = (MenuComponent)iterator.next();
menu.setBreadCrumb(breadCrumbDelimiter);
}
}
public void buildBreadCrumbs(String delimiter) {
this.breadCrumbDelimiter = delimiter;
buildBreadCrumbs();
}
}
/*
* PermissionsAdapter.java
*
* Created on April 29, 2002, 10:15 PM
*/
package net.sf.navigator.menu;
/**
* Defines a pluggable adapter into the menu framework that is used for
* checking permissions on menus.
*
* @author ssayles
*/
public interface PermissionsAdapter {
/**
* If the menu is allowed, this should return true.
*
* @return whether or not the menu is allowed.
*/
public boolean isAllowed(MenuComponent menu);
}
/*
* RolesPermissionsAdapter.java
*
* Created on December 7, 2002 2:25 PM
*/
package net.sf.navigator.menu;
import javax.servlet.http.HttpServletRequest;
import java.util.regex.Pattern;
/**
* This class used container-managed security to check access
* to menus. The roles are set in menu-config.xml.
*
* @author <a href="mailto:matt@raibledesigns.com">Matt Raible</a>
*/
public class RolesPermissionsAdapter implements PermissionsAdapter {
private Pattern delimiters = Pattern.compile("(?<!\\\\),");
private HttpServletRequest request;
public RolesPermissionsAdapter(HttpServletRequest request) {
this.request = request;
}
/**
* If the menu is allowed, this should return true.
*
* @return whether or not the menu is allowed.
*/
public boolean isAllowed(MenuComponent menu) {
if (menu.getRoles() == null) {
return true; // no roles define, allow everyone
} else {
// Get the list of roles this menu allows
String[] allowedRoles = delimiters.split(menu.getRoles());
for (int i=0; i < allowedRoles.length; i++) {
if (request.isUserInRole(allowedRoles[i])) {
return true;
}
}
}
return false;
}
}
/*
* AbstractMenuDisplayer.java
*
* Created on March 30, 2002, 3:34 PM
*/
package net.sf.navigator.displayer;
import net.sf.navigator.menu.MenuComponent;
import net.sf.navigator.menu.PermissionsAdapter;
import net.sf.navigator.util.MessageResources;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import java.io.IOException;
/**
* Abstract implementation of <code>MenuDisplayer</code> that can be used as
* a basis for other menu displayers.
*
* @author ssayles
* @version
*/
public abstract class AbstractMenuDisplayer implements MenuDisplayer {
//~ Instance fields ========================================================
protected final transient Log log = LogFactory.getLog(getClass());
protected String name;
protected MessageResources displayStrings;
protected JspWriter out;
protected String target;
/** Holds value of property permissionsAdapter. */
protected PermissionsAdapter permissionsAdapter;
protected MenuDisplayerMapping mapping;
//~ Methods ================================================================
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getConfig() {
String config = null;
if (displayStrings != null) {
config = displayStrings.getConfig();
}
return config;
}
public void setConfig(String config) {
displayStrings = MessageResources.getMessageResources(config);
}
public String getTarget() {
return target;
}
/**
* Convenience method that will first return the target for the displayer
* if it is not null. If the displayer target is null, then it will
* return <code>menu.getTarget()</code>.
*
* @return the target for the menu link.
*/
protected String getTarget(MenuComponent menu) {
String theTarget = null;
if (target == null) {
if (menu.getTarget() != null) {
theTarget = menu.getTarget();
}
} else {
theTarget = target;
}
return theTarget;
}
public void setTarget(String target) {
this.target = target;
}
/**
* Getter for property permissionsAdapter.
* @return Value of property permissionsAdapter.
*/
public PermissionsAdapter getPermissionsAdapter() {
return this.permissionsAdapter;
}
/**
* Setter for property permissionsAdapter.
* @param permissionsAdapter New value of property permissionsAdapter.
*/
public void setPermissionsAdapter(PermissionsAdapter permissionsAdapter) {
this.permissionsAdapter = permissionsAdapter;
}
/**
* Lifecycle method that should be called when the <code>MenuDisplayer</code>
* is being prepared for use.
*
* @param pageContext The JSP pageContext to give the displayer access
* to any resources it may need.
* @param mapping The menu displayer mapping used to embody the xml
* definition.
*/
public void init(PageContext pageContext, MenuDisplayerMapping mapping) {
this.out = pageContext.getOut();
this.mapping = mapping;
}
public abstract void display(MenuComponent menu)
throws JspException, IOException;
public void end(PageContext pageContext) {}
/**
* Returns <code>true</code> if the specified component is usable.
* If <code>permissionsAdapter</code> is not defined, this method will
* return <code>true</code>. Otherwise, the adapter will be used to check
* permissions on the menu.
*
* @return <code>true</code> if the menu component is usable.
* @param menu The menu component.
*/
public boolean isAllowed(MenuComponent menu) {
return permissionsAdapter == null || permissionsAdapter.isAllowed(menu);
}
}
/*
* SimpleMenuDisplayer.java
*
* Created on February 15, 2001, 11:14 AM
*/
package net.sf.navigator.displayer;
import net.sf.navigator.menu.MenuComponent;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import java.io.IOException;
/**
*
* @author ssayles
* @version
*/
public class SimpleMenuDisplayer extends MessageResourcesMenuDisplayer {
//~ Static fields/initializers =============================================
protected static final String nbsp = NBSP;
//~ Methods ================================================================
public void init(PageContext pageContext, MenuDisplayerMapping mapping) {
super.init(pageContext, mapping);
try {
out.println(displayStrings.getMessage("smd.style"));
} catch (Exception e) {
log.error(e.getMessage());
}
}
public void display(MenuComponent menu) throws JspException, IOException {
if (isAllowed(menu)) {
out.println(displayStrings.getMessage("smd.menu.top"));
displayComponents(menu, 0);
out.println(displayStrings.getMessage("smd.menu.bottom"));
}
}
protected void displayComponents(MenuComponent menu, int level)
throws JspException, IOException {
MenuComponent[] components = menu.getMenuComponents();
if (components.length > 0) {
out.println(displayStrings.getMessage("smd.menu.item.top",
getSpace(level) +
displayStrings.getMessage("smd.menu.item.image.bullet") +
getMessage(menu.getTitle())));
for (int i = 0; i < components.length; i++) {
if (components[i].getMenuComponents().length > 0) {
if (isAllowed(components[i])) {
displayComponents(components[i], level + 1);
}
} else {
if (isAllowed(components[i])) {
out.println(displayStrings.getMessage("smd.menu.item",
components[i].getUrl(),
super.getMenuTarget(components[i]),
super.getMenuToolTip(components[i]),
this.getSpace(level + 1) + getImage(components[i]) +
this.getMessage(components[i].getTitle())));
}
}
}
} else {
out.println(displayStrings.getMessage("smd.menu.item",
menu.getUrl(), super.getMenuTarget(menu),
super.getMenuToolTip(menu),
this.getSpace(level) + getImage(menu) +
getMessage(menu.getTitle())));
}
}
protected String getSpace(int length) {
String space = EMPTY;
for (int i = 0; i < length; i++) {
space = space + nbsp + nbsp;
}
return space;
}
protected String getImage(MenuComponent menu) {
String imageTag;
if ((menu.getImage() == null) || (menu.getImage().equals(EMPTY))) {
imageTag = EMPTY;
} else {
imageTag =
displayStrings.getMessage("smd.menu.item.image",
menu.getImage(), super.getMenuToolTip(menu));
}
return imageTag;
}
}
package net.sf.navigator.displayer;
import net.sf.navigator.menu.MenuComponent;
import javax.servlet.jsp.JspException;
import java.io.IOException;
/**
*
* @author <a href="mailto:matt@raibledesigns.com">Matt Raible</a>
* @version 1.0
*/
public class TabbedMenuDisplayer extends ListMenuDisplayer {
//~ Methods ================================================================
public void display(MenuComponent menu) throws JspException, IOException {
if (isAllowed(menu)) {
displayComponents(menu, 0);
}
}
protected void displayComponents(MenuComponent menu, int level)
throws JspException, IOException {
MenuComponent[] components = menu.getMenuComponents();
if (components.length > 0) {
out.print("\t<li>");
String menuClass = "submenu";
if (level >= 1) {
menuClass = "deepmenu";
}
if (menu.getUrl() == null) {
log.info("The Menu '" + getMessage(menu.getTitle()) +
"' does not have a location defined, using first submenu's location");
menu.setUrl(components[0].getUrl());
}
out.print(displayStrings.getMessage("tmd.menu.tab",
menu.getUrl(), super.getMenuToolTip(menu),
getExtra(menu), getMessage(menu.getTitle())));
for (int i = 0; i < components.length; i++) {
// check the permissions on this component
if (isAllowed(components[i])) {
if (components[i].getMenuComponents().length > 0) {
// and an <li> for submenus (but not deepmenus)
if (menuClass.equals("submenu")) {
out.print("<li>");
}
displayComponents(components[i], level + 1);
out.println("</ul></li>");
if (i == (components[i].getMenuComponents().length - 1)) { // last one
out.println("</li>");
}
} else {
out.println(displayStrings.getMessage("tmd.menu.item",
components[i].getUrl(),
super.getMenuToolTip(components[i]),
super.getExtra(components[i]),
this.getMessage(components[i].getTitle())));
}
}
}
// close the </ul> for the top menu
if (menuClass.equals("submenu")) {
out.println("\t</ul>");
}
out.print("\t</li>");
} else {
out.println(displayStrings.getMessage("tmd.menu.item",
menu.getUrl(), super.getMenuToolTip(menu),
super.getExtra(menu), getMessage(menu.getTitle())));
}
}
}
package net.sf.navigator.displayer;
import net.sf.navigator.menu.MenuComponent;
import javax.servlet.jsp.JspException;
import java.io.IOException;
/**
*
* @author <a href="mailto:matt@raibledesigns.com">Matt Raible</a>
* @version 1.0
*/
public class CSSListMenuDisplayer extends ListMenuDisplayer {
//~ Methods ================================================================
public void display(MenuComponent menu) throws JspException, IOException {
if (isAllowed(menu)) {
out.println(displayStrings.getMessage("ccslm.menu.top",
(hasViewableChildren(menu)) ? " class=\"menubar\"" : ""));
displayComponents(menu, 0);
out.println(displayStrings.getMessage("lmd.menu.bottom"));
}
}
protected void displayComponents(MenuComponent menu, int level)
throws JspException, IOException {
if (menu.getUrl() == null) {
// http://issues.appfuse.org/browse/SM-48 - javascript:void(0) works better than #
menu.setUrl("javascript:void(0)");
}
MenuComponent[] components = menu.getMenuComponents();
if (components.length > 0) {
// if there is a location/page/action tag on base item use it
if (components.length == 0){
out.println(displayStrings.getMessage("lmd.menu.item",
menu.getUrl(),
super.getMenuToolTip(menu),
getExtra(menu),
this.getMessage(menu.getTitle())));
} else {
out.println(displayStrings.getMessage("ccslm.menubar.top",
menu.getUrl(), getExtra(menu), this.getMessage(menu.getTitle())));
if (hasViewableChildren(menu)) {
out.println("\t\t<ul>");
}
}
for (int i = 0; i < components.length; i++) {
// check the permissions on this component
if (isAllowed(components[i])) {
if (components[i].getMenuComponents().length > 0) {
if (!hasViewableChildren(components[i])) {
out.println("<li>");
} else {
out.println("<li class=\"menubar\">");
}
displayComponents(components[i], level + 1);
out.println((hasViewableChildren(components[i]) ? "\t\t</ul>\t</li>\n" : "\t</li>\n"));
//out.println(displayStrings.getMessage("lmd.menu.actuator.bottom"));
} else {
out.println(displayStrings.getMessage("lmd.menu.item",
components[i].getUrl(),
super.getMenuToolTip(components[i]),
getExtra(components[i]),
this.getMessage(components[i].getTitle())));
}
}
}
// close the </ul> for the top menu
if (level == 0 && hasViewableChildren(menu)) {
out.println("</ul>");
}
} else {
if (menu.getParent() == null) {
out.println(displayStrings.getMessage("lmd.menu.standalone",
menu.getUrl(),
super.getMenuToolTip(menu),
getExtra(menu),
getMessage(menu.getTitle())));
} else {
out.println(displayStrings.getMessage("lmd.menu.item",
menu.getUrl(),
super.getMenuToolTip(menu),
getExtra(menu),
getMessage(menu.getTitle())));
}
}
}
private boolean hasViewableChildren(MenuComponent menu) {
for (int i = 0; i < menu.getMenuComponents().length; i++) {
if (isAllowed(menu.getMenuComponents()[i])) {
return true;
}
}
return false;
}
}