/*
* RHQ Management Platform
* Copyright (C) 2005-2014 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.rhq.coregui.client.menu;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.History;
import com.smartgwt.client.widgets.HTMLFlow;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.common.ProductInfo;
import org.rhq.coregui.client.CoreGUI;
import org.rhq.coregui.client.PermissionsLoadedListener;
import org.rhq.coregui.client.PermissionsLoader;
import org.rhq.coregui.client.UserSessionManager;
import org.rhq.coregui.client.admin.AdministrationView;
import org.rhq.coregui.client.admin.AgentPluginTableView;
import org.rhq.coregui.client.admin.DownloadsView;
import org.rhq.coregui.client.admin.ServerPluginTableView;
import org.rhq.coregui.client.admin.SystemSettingsView;
import org.rhq.coregui.client.admin.roles.RolesView;
import org.rhq.coregui.client.admin.storage.StorageNodeAdminView;
import org.rhq.coregui.client.admin.templates.AlertDefinitionTemplateTypeView;
import org.rhq.coregui.client.admin.templates.DriftDefinitionTemplateTypeView;
import org.rhq.coregui.client.admin.templates.IgnoreResourceTypesView;
import org.rhq.coregui.client.admin.templates.MetricTemplateTypeView;
import org.rhq.coregui.client.admin.templates.MissingPolicyResourceTypesView;
import org.rhq.coregui.client.admin.topology.AffinityGroupTableView;
import org.rhq.coregui.client.admin.topology.AgentTableView;
import org.rhq.coregui.client.admin.topology.PartitionEventTableView;
import org.rhq.coregui.client.admin.topology.ServerTableView;
import org.rhq.coregui.client.admin.users.UsersView;
import org.rhq.coregui.client.alert.AlertHistoryView;
import org.rhq.coregui.client.bundle.BundleTopView;
import org.rhq.coregui.client.components.AboutModalWindow;
import org.rhq.coregui.client.components.view.ViewName;
import org.rhq.coregui.client.dashboard.DashboardsView;
import org.rhq.coregui.client.dashboard.portlets.platform.PlatformSummaryPortlet;
import org.rhq.coregui.client.drift.DriftHistoryView;
import org.rhq.coregui.client.footer.FavoritesMenu;
import org.rhq.coregui.client.help.HelpView;
import org.rhq.coregui.client.inventory.InventoryView;
import org.rhq.coregui.client.inventory.resource.detail.configuration.ResourceConfigurationHistoryListView;
import org.rhq.coregui.client.inventory.resource.discovery.ResourceAutodiscoveryView;
import org.rhq.coregui.client.operation.OperationHistoryView;
import org.rhq.coregui.client.report.AlertDefinitionReportView;
import org.rhq.coregui.client.report.ReportTopView;
import org.rhq.coregui.client.report.inventory.DriftComplianceReport;
import org.rhq.coregui.client.report.inventory.ResourceInstallReport;
import org.rhq.coregui.client.report.measurement.MeasurementOOBView;
import org.rhq.coregui.client.report.tag.TaggedView;
import org.rhq.coregui.client.util.enhanced.EnhancedVLayout;
import org.rhq.coregui.client.util.message.MessageBar;
import org.rhq.coregui.client.util.message.MessageCenterView;
import org.rhq.coregui.client.util.preferences.UserPreferenceNames.UiSubsystem;
/**
* @author Greg Hinkle
* @author Joseph Marques
* @author Ian Springer
* @author Libor Zoubek
*/
public class MenuBarView extends EnhancedVLayout {
public static final String MSG_CENTER_BTN_CONTENT = "<span class='fa fa-flag'> ";
public static final String BTN_FAV_ID = "fav-btn";
public static final String BTN_MSG_CENTER_ID = "msg-center-btn";
public static final MenuItem[] MENU_ITEMS = {
new MenuItem(DashboardsView.VIEW_ID),
new MenuItem(InventoryView.VIEW_ID)
.subItems(
new MenuItem(InventoryView.RESOURCES_SECTION_VIEW_ID, true),
new MenuItem(ResourceAutodiscoveryView.VIEW_ID, Permission.MANAGE_INVENTORY, InventoryView.VIEW_ID, InventoryView.RESOURCES_SECTION_VIEW_ID),
new MenuItem(InventoryView.PAGE_ALL_RESOURCES, InventoryView.VIEW_ID, InventoryView.RESOURCES_SECTION_VIEW_ID),
new MenuItem(InventoryView.PAGE_PLATFORMS, InventoryView.VIEW_ID, InventoryView.RESOURCES_SECTION_VIEW_ID),
new MenuItem(InventoryView.PAGE_SERVERS_TOP, InventoryView.VIEW_ID, InventoryView.RESOURCES_SECTION_VIEW_ID),
new MenuItem(InventoryView.PAGE_SERVERS, InventoryView.VIEW_ID, InventoryView.RESOURCES_SECTION_VIEW_ID),
new MenuItem(InventoryView.PAGE_SERVICES, InventoryView.VIEW_ID, InventoryView.RESOURCES_SECTION_VIEW_ID),
new MenuItem(InventoryView.PAGE_IGNORED_RESOURCES, InventoryView.VIEW_ID, InventoryView.RESOURCES_SECTION_VIEW_ID),
new MenuItem(InventoryView.PAGE_UNAVAIL_SERVERS, InventoryView.VIEW_ID, InventoryView.RESOURCES_SECTION_VIEW_ID),
new MenuItem(InventoryView.GROUPS_SECTION_VIEW_ID, true),
new MenuItem(InventoryView.PAGE_ALL_GROUPS, InventoryView.VIEW_ID, InventoryView.GROUPS_SECTION_VIEW_ID),
new MenuItem(InventoryView.PAGE_DYNAGROUP_DEFINITIONS, Permission.MANAGE_INVENTORY, InventoryView.VIEW_ID, InventoryView.GROUPS_SECTION_VIEW_ID),
new MenuItem(InventoryView.PAGE_COMPATIBLE_GROUPS, InventoryView.VIEW_ID, InventoryView.GROUPS_SECTION_VIEW_ID),
new MenuItem(InventoryView.PAGE_MIXED_GROUPS, InventoryView.VIEW_ID, InventoryView.GROUPS_SECTION_VIEW_ID),
new MenuItem(InventoryView.PAGE_PROBLEM_GROUPS, InventoryView.VIEW_ID, InventoryView.GROUPS_SECTION_VIEW_ID)
),
new MenuItem(ReportTopView.VIEW_ID)
.subItems(
new MenuItem(ReportTopView.SECTION_SUBSYSTEMS_VIEW_ID, true),
new MenuItem(TaggedView.VIEW_ID,ReportTopView.VIEW_ID,ReportTopView.SECTION_SUBSYSTEMS_VIEW_ID),
new MenuItem(MeasurementOOBView.VIEW_ID,ReportTopView.VIEW_ID,ReportTopView.SECTION_SUBSYSTEMS_VIEW_ID),
new MenuItem(ResourceConfigurationHistoryListView.VIEW_ID,Permission.MANAGE_INVENTORY,ReportTopView.VIEW_ID,ReportTopView.SECTION_SUBSYSTEMS_VIEW_ID),
new MenuItem(OperationHistoryView.SUBSYSTEM_VIEW_ID,Permission.MANAGE_INVENTORY,ReportTopView.VIEW_ID,ReportTopView.SECTION_SUBSYSTEMS_VIEW_ID),
new MenuItem(AlertHistoryView.SUBSYSTEM_VIEW_ID,Permission.MANAGE_INVENTORY,ReportTopView.VIEW_ID,ReportTopView.SECTION_SUBSYSTEMS_VIEW_ID),
new MenuItem(AlertDefinitionReportView.VIEW_ID,ReportTopView.VIEW_ID,ReportTopView.SECTION_SUBSYSTEMS_VIEW_ID),
new MenuItem(DriftHistoryView.SUBSYSTEM_VIEW_ID,Permission.MANAGE_INVENTORY,ReportTopView.VIEW_ID,ReportTopView.SECTION_SUBSYSTEMS_VIEW_ID),
new MenuItem(ReportTopView.SECTION_INVENTORY_VIEW_ID, true),
new MenuItem(PlatformSummaryPortlet.VIEW_ID,ReportTopView.VIEW_ID,ReportTopView.SECTION_INVENTORY_VIEW_ID),
new MenuItem(ResourceInstallReport.VIEW_ID,Permission.MANAGE_INVENTORY,ReportTopView.VIEW_ID,ReportTopView.SECTION_INVENTORY_VIEW_ID),
new MenuItem(DriftComplianceReport.VIEW_ID,Permission.MANAGE_INVENTORY,ReportTopView.VIEW_ID,ReportTopView.SECTION_INVENTORY_VIEW_ID)
),
new MenuItem(BundleTopView.VIEW_ID),
new MenuItem(AdministrationView.VIEW_ID)
.subItems(
new MenuItem(UsersView.VIEW_ID.withTitle(AdministrationView.SECTION_SECURITY_VIEW_ID.getTitle()),
AdministrationView.VIEW_ID, AdministrationView.SECTION_SECURITY_VIEW_ID)
.subItems(
new MenuItem(UsersView.VIEW_ID, AdministrationView.VIEW_ID,AdministrationView.SECTION_SECURITY_VIEW_ID),
new MenuItem(RolesView.VIEW_ID, AdministrationView.VIEW_ID,AdministrationView.SECTION_SECURITY_VIEW_ID)
),
new MenuItem(ServerTableView.VIEW_ID.withTitle(AdministrationView.SECTION_TOPOLOGY_VIEW_ID.getTitle()),
AdministrationView.VIEW_ID, AdministrationView.SECTION_TOPOLOGY_VIEW_ID)
.subItems(
new MenuItem(ServerTableView.VIEW_ID, AdministrationView.VIEW_ID,AdministrationView.SECTION_TOPOLOGY_VIEW_ID),
new MenuItem(StorageNodeAdminView.VIEW_ID, AdministrationView.VIEW_ID,AdministrationView.SECTION_TOPOLOGY_VIEW_ID),
new MenuItem(AgentTableView.VIEW_ID, AdministrationView.VIEW_ID,AdministrationView.SECTION_TOPOLOGY_VIEW_ID),
new MenuItem(AffinityGroupTableView.VIEW_ID, AdministrationView.VIEW_ID,AdministrationView.SECTION_TOPOLOGY_VIEW_ID),
new MenuItem(PartitionEventTableView.VIEW_ID, AdministrationView.VIEW_ID,AdministrationView.SECTION_TOPOLOGY_VIEW_ID)
),
new MenuItem(
DownloadsView.VIEW_ID.withTitle(AdministrationView.SECTION_CONFIGURATION_VIEW_ID.getTitle()),
Permission.MANAGE_SETTINGS, AdministrationView.VIEW_ID,AdministrationView.SECTION_CONFIGURATION_VIEW_ID)
.subItems(
new MenuItem(SystemSettingsView.VIEW_ID,Permission.MANAGE_SETTINGS, AdministrationView.VIEW_ID,AdministrationView.SECTION_CONFIGURATION_VIEW_ID),
new MenuItem(AlertDefinitionTemplateTypeView.VIEW_ID, AdministrationView.VIEW_ID,AdministrationView.SECTION_CONFIGURATION_VIEW_ID),
new MenuItem(DriftDefinitionTemplateTypeView.VIEW_ID, AdministrationView.VIEW_ID,AdministrationView.SECTION_CONFIGURATION_VIEW_ID),
new MenuItem(MetricTemplateTypeView.VIEW_ID, AdministrationView.VIEW_ID,AdministrationView.SECTION_CONFIGURATION_VIEW_ID),
new MenuItem(IgnoreResourceTypesView.VIEW_ID, AdministrationView.VIEW_ID,AdministrationView.SECTION_CONFIGURATION_VIEW_ID),
new MenuItem(MissingPolicyResourceTypesView.VIEW_ID, AdministrationView.VIEW_ID,AdministrationView.SECTION_CONFIGURATION_VIEW_ID),
new MenuItem(DownloadsView.VIEW_ID, AdministrationView.VIEW_ID,AdministrationView.SECTION_CONFIGURATION_VIEW_ID),
new MenuItem(AgentPluginTableView.VIEW_ID, Permission.MANAGE_SETTINGS, AdministrationView.VIEW_ID,AdministrationView.SECTION_CONFIGURATION_VIEW_ID),
new MenuItem(ServerPluginTableView.VIEW_ID, Permission.MANAGE_SETTINGS, AdministrationView.VIEW_ID,AdministrationView.SECTION_CONFIGURATION_VIEW_ID)
),
new MenuItem(
AdministrationView.PAGE_REPOS_VIEW_ID.withTitle(AdministrationView.SECTION_CONTENT_VIEW_ID.getTitle()),
Permission.MANAGE_REPOSITORIES, AdministrationView.VIEW_ID, AdministrationView.SECTION_CONTENT_VIEW_ID)
.subItems(
new MenuItem(AdministrationView.PAGE_CONTENT_SOURCES_VIEW_ID, Permission.MANAGE_REPOSITORIES, AdministrationView.VIEW_ID,AdministrationView.SECTION_CONTENT_VIEW_ID),
new MenuItem(AdministrationView.PAGE_REPOS_VIEW_ID, AdministrationView.VIEW_ID,AdministrationView.SECTION_CONTENT_VIEW_ID)
)
),
new MenuItem(HelpView.VIEW_ID)
};
private static int topLvlItems = 0;
private static final String NAV_BAR_UL_ID = "navBarUlId";
public static final ViewName LOGOUT_VIEW_ID = new ViewName("LogOut", MSG.view_menuBar_logout());
private final ProductInfo productInfo = CoreGUI.get().getProductInfo();
private String currentlySelectedSection = DashboardsView.VIEW_ID.getName();
private MessageBar messageBar;
private MessageCenterView messageCenter;
private FavoritesMenu favoritesMenu;
private Set<Permission> globalPermissions;
private Map<UiSubsystem, Boolean> showSubsystems;
public MenuBarView() {
super();
setStyleName("overflowVisible"); // force overflow:visible via style - workaround menu issue in FF
}
@Override
protected void onInit() {
super.onInit();
messageCenter = new MessageCenterView();
favoritesMenu = new FavoritesMenu();
messageBar = new MessageBar();
messageBar.setVisible(false);
injectMenuFunctions(this);
new PermissionsLoader().loadExplicitGlobalPermissions(new PermissionsLoadedListener() {
@Override
public void onPermissionsLoaded(Set<Permission> permissions) {
globalPermissions = (permissions != null) ? permissions : EnumSet.noneOf(Permission.class);
showSubsystems = UserSessionManager.getUserPreferences().getShowUiSubsystems();
for (MenuItem item : MENU_ITEMS) {
if ((item.getView() == ReportTopView.VIEW_ID && !showSubsystems.get(UiSubsystem.REPORTS))
|| (item.getView() == BundleTopView.VIEW_ID && !showSubsystems.get(UiSubsystem.CONTENT))
|| (item.getView() == AdministrationView.VIEW_ID && !showSubsystems
.get(UiSubsystem.ADMINISTRATION))) {
item.setHidden(true);
} else {
updateMenuVisibility(item);
}
}
addMember(new LinkBar());
addMember(messageBar);
}
});
}
private void updateMenuVisibility(MenuItem item) {
// set visibility based on permission
if (item.getPermission() != null) {
item.setHidden(!globalPermissions.contains(item.getPermission()));
}
if (TaggedView.VIEW_ID.getName().equals(item.getView().getName())) { // Reports->Tags shown only for RHQ
item.setHidden(!CoreGUI.isTagsEnabledForUI());
}
for (MenuItem child : item.getSubItems()) {
updateMenuVisibility(child);
}
}
// This is our JSNI method that will be called on form submit
private native void injectMenuFunctions(MenuBarView view) /*-{
$wnd.__gwt_clearMessageBar = $entry(function(){
view.@org.rhq.coregui.client.menu.MenuBarView::clearMessageBar()();
});
$wnd.__gwt_showMessageCenter = $entry(function(){
view.@org.rhq.coregui.client.menu.MenuBarView::showMessageCenterWindow()();
});
$wnd.__gwt_showFavoritesMenu = $entry(function(){
view.@org.rhq.coregui.client.menu.MenuBarView::showFavoritesMenu()();
});
$wnd.__gwt_showAboutBox = $entry(function(){
view.@org.rhq.coregui.client.menu.MenuBarView::showAboutBox()();
});
}-*/;
// called via JSNI - user menu button
public void clearMessageBar() {
messageBar.clearMessage(true);
}
// called via JSNI - fav menu button
public void showFavoritesMenu() {
clearMessageBar();
favoritesMenu.show();
this.favoritesMenu.showMenu(DOM.getElementById(BTN_FAV_ID).getAbsoluteBottom(), DOM.getElementById(BTN_FAV_ID)
.getAbsoluteLeft());
}
// called via JSNI - msgcenter menu button
public void showMessageCenterWindow() {
this.messageCenter.showMessageCenterWindow();
}
// called via JSNI - RHQ on logo click
public void showAboutBox() {
new AboutModalWindow(productInfo).show();
}
public MessageBar getMessageBar() {
return messageBar;
}
public MessageCenterView getMessageCenter() {
return messageCenter;
}
class LinkBar extends HTMLFlow implements ValueChangeHandler<String> {
private final Map<String, String> sectionNameToLinkID = new HashMap<String, String>();
LinkBar() {
super();
setStyleName("overflowVisible"); // force overflow:visible via style - workaround menu issue in FF
this.setContents(createBarContent());
History.addValueChangeHandler(this);
}
@Override
protected void onDraw() {
updateActiveMenuItem(History.getToken());
super.onDraw();
injectJQueryCode();
}
// add jQuery magic for main navbar
private native void injectJQueryCode() /*-{
$wnd.$('.navbar-btn-item').on('mouseenter', function() {$wnd.$(this).parent().parent().addClass('navbar-btn-item-hover')});
$wnd.$('.navbar-btn-item').on('mouseleave', function() {$wnd.$(this).parent().parent().removeClass('navbar-btn-item-hover')});
}-*/;
private String getViewLink(ViewName view) {
return "<a href='#" + view.getName() + "'>" + view.getTitle() + "</a>";
}
private String createBarContent() {
Subject user = UserSessionManager.getSessionSubject();
StringBuilder sb = new StringBuilder();
sb.append("<nav class='navbar navbar-default navbar-pf' role='navigation'>"
+"<div class='navbar-header'>"
+"<button type='button' class='navbar-toggle collapsed' data-toggle='collapse' data-target='.navbar-collapse-1'>"
+"<span class='sr-only'>Toggle navigation</span>"
+"<span class='icon-bar'></span>"
+"<span class='icon-bar'></span>"
+"<span class='icon-bar'></span>"
+"</button>"
+"<a class='navbar-brand' href='#' onclick='__gwt_showAboutBox(); return false;'>"
+ "<img class='navbar-logo' src='img/"
+ ("RHQ".equals(CoreGUI.get().getProductInfo().getShortName()) ? "logo" : "RH-JON-Login-Logo")
+ ".png'/>"
+"</a>"
+"</div>"
+"<div class='navbar-collapse navbar-collapse-1 collapse'>"
+"<ul class='nav navbar-nav navbar-utility'>"
+"<li>"
+"<a id='"+BTN_FAV_ID+"' onclick='__gwt_showFavoritesMenu(); return false;'><i class='fa fa-star'></i><b class='caret'></b></a>"
+"</li>"
+"<li>"
+"<a id='"+BTN_MSG_CENTER_ID+"' onclick='__gwt_showMessageCenter(); return false;'>"+MSG_CENTER_BTN_CONTENT+"0</a>"
+"</li>"
+ "<li class='dropdown'>"
+ "<a onclick='__gwt_clearMessageBar(); return false;' class='dropdown-toggle' data-toggle='dropdown'>"
+"<span class='pficon pficon-user'></span>"
+user.getName()+" <b class='caret'></b>"
+"</a>"
+"<ul class='dropdown-menu'>"
+ "<li><a href='#Administration/Security/Users/"
+ user.getId()
+ "'>"
+ MSG.common_title_settings()
+ "</a></li>"
+ "<li class='divider'></li>"
+"<li>"
+"<a href='#"+LOGOUT_VIEW_ID.getName()+"'>"+LOGOUT_VIEW_ID.getTitle()+"</a>"
+"</li>"
+"</ul>"
+"</li>"
+"</ul>"
+"<ul id='" + NAV_BAR_UL_ID +"' class='nav navbar-nav navbar-primary'>"
+ getMenuItems()
+"</ul>"
+"</div>"
+ "</nav>");
return sb.toString();
}
private String getMenuItems() {
StringBuilder sb = new StringBuilder();
topLvlItems = -1;
for (MenuItem menuItem : MENU_ITEMS) {
if (!menuItem.isHidden()) {
++topLvlItems;
sb.append(getMenuItemString(menuItem, String.valueOf(topLvlItems), 0));
sectionNameToLinkID.put(menuItem.getView().getName(), "menu" + topLvlItems);
}
}
return sb.toString();
}
private String getMenuItemString(MenuItem menuItem, String index, int level) {
if (menuItem.isHidden()) {
return "";
}
String menuId = "menu"+index;
String menuLevel = "dropdown";
if (level > 0) {
menuId = "";
menuLevel = "dropdown-submenu";
}
StringBuilder sb = new StringBuilder();
ViewName sectionName = menuItem.getView();
boolean hasChildren = menuItem.hasVisibleChildren();
if (!hasChildren) {
sb.append("<li id='" + menuId +"'><a href='#" + sectionName.getName() + "'>" + sectionName.getTitle()
+ "</a></li>");
}
else {
StringBuilder item = new StringBuilder("<li id='" + menuId +"' class='"+menuLevel+"'>");
if (level == 0) {
item.append("<div class='navbar-btn-group'>");
item.append("<a class='navbar-btn-item nbi-link' href='#"+sectionName.getName()+"'>" + sectionName.getTitle() + "</a>");
item.append("<a class='navbar-btn-item nbi-caret' data-toggle='dropdown'><b class='caret'></b></a>");
} else {
item.append("<a href='#"+sectionName.getName()+"'>" + sectionName.getTitle() + "</a>");
}
item.append("<ul class='dropdown-menu'>");
int subMenuIndex = 0;
for (MenuItem subMenu : menuItem.getSubItems()) {
ViewName subItem = subMenu.getView();
if (subMenu.isSeparator()) {
if (subMenuIndex == 0) { // when first is separator we skip divider line
item.append("<li class='dropdown-header'>"+subItem.getTitle()+"</li>");
} else {
item.append("<li class='divider'></li><li class='dropdown-header'>"+subItem.getTitle()+"</li>");
}
}
else {
item.append(getMenuItemString(subMenu, "", level + 1));
}
subMenuIndex++;
}
item.append("</ul>");
if (level == 0) {
item.append("</div>");
}
item.append("</li>");
sb.append(item.toString());
}
return sb.toString();
}
@Override
public void onValueChange(ValueChangeEvent<String> stringValueChangeEvent) {
updateActiveMenuItem(stringValueChangeEvent.getValue());
}
private void updateActiveMenuItem(String viewPath) {
String topViewId = viewPath.split("/")[0];
if ("Resource".equals(topViewId)) {
topViewId = InventoryView.VIEW_ID.getName();
}
currentlySelectedSection = topViewId;
for (MenuItem item : MENU_ITEMS) {
if (!item.isHidden()) {
updateLinkStyle(item.getView().getName());
}
}
}
private void updateLinkStyle(String sectionName) {
String className;
if (sectionName.equals(currentlySelectedSection)) {
className = "active";
} else {
className = "";
}
String itemId = this.sectionNameToLinkID.get(sectionName);
DOM.getElementById(itemId).setClassName(className);
}
}
public static int getUlLeftCoordinate() {
int left = DOM.getElementById("menu" + topLvlItems).getAbsoluteLeft()
+ DOM.getElementById("menu" + topLvlItems).getClientWidth() + 10;
return left;
}
public static int getUlWidth() {
int ulWidth = DOM.getElementById(NAV_BAR_UL_ID).getParentElement().getClientWidth();
return ulWidth;
}
public static class MenuItem {
private final boolean separator;
private final ArrayList<MenuItem> subItems;
private final ViewName view;
private final Permission permission;
private boolean hidden;
public MenuItem(ViewName view) {
this(view, false, null);
}
public MenuItem(ViewName view, Permission p) {
this(view, false, p);
}
public MenuItem(ViewName view, Permission p, ViewName... parents) {
this(fromParents(view, parents), false, p);
}
public MenuItem(ViewName view, ViewName... parents) {
this(fromParents(view, parents), false, null);
}
private static ViewName fromParents(ViewName view, ViewName... parents) {
StringBuilder sb = new StringBuilder();
for (ViewName v : parents) {
sb.append(v.getName()+"/");
}
return new ViewName(sb.toString()+view.getName(),view.getTitle());
}
public MenuItem(ViewName view, boolean separator) {
this(view,separator,null);
}
public MenuItem(ViewName view, boolean separator, Permission p) {
this.view = view;
this.separator = separator;
this.subItems = new ArrayList<MenuBarView.MenuItem>();
this.permission = p;
}
public boolean hasVisibleChildren() {
for (MenuItem child : getSubItems()) {
if (!child.isHidden()) {
return true;
}
}
return false;
}
public MenuItem subItems(MenuItem... items) {
getSubItems().addAll(Arrays.asList(items));
return this;
}
public ArrayList<MenuItem> getSubItems() {
return subItems;
}
public boolean isSeparator() {
return separator;
}
public ViewName getView() {
return view;
}
public Permission getPermission() {
return permission;
}
public void setHidden(boolean hidden) {
this.hidden = hidden;
}
public boolean isHidden() {
return hidden;
}
}
}