/* * 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.footer; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import com.google.gwt.user.client.rpc.AsyncCallback; import com.smartgwt.client.widgets.menu.Menu; import com.smartgwt.client.widgets.menu.MenuItem; import com.smartgwt.client.widgets.menu.MenuItemSeparator; import com.smartgwt.client.widgets.menu.events.MenuItemClickEvent; import org.rhq.core.domain.criteria.ResourceCriteria; import org.rhq.core.domain.criteria.ResourceGroupCriteria; import org.rhq.core.domain.resource.Resource; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.domain.resource.group.ResourceGroup; import org.rhq.core.domain.resource.group.composite.ResourceGroupComposite; import org.rhq.core.domain.util.PageList; import org.rhq.coregui.client.CoreGUI; import org.rhq.coregui.client.ImageManager; import org.rhq.coregui.client.LinkManager; import org.rhq.coregui.client.Messages; import org.rhq.coregui.client.UserSessionManager; import org.rhq.coregui.client.gwt.GWTServiceLookup; import org.rhq.coregui.client.inventory.resource.AncestryUtil; import org.rhq.coregui.client.inventory.resource.type.ResourceTypeRepository; import org.rhq.coregui.client.inventory.resource.type.ResourceTypeRepository.TypesLoadedCallback; /** * @author Jay Shaughnessy */ public class FavoritesMenu extends Menu { private Messages MSG = CoreGUI.getMessages(); final Menu favoriteResourcesMenu; final Menu favoriteGroupsMenu; final Menu recentlyViewedMenu; public FavoritesMenu() { super(); setSubmenuDirection("left"); // these are the child menus directly under the main favorites button favoriteResourcesMenu = new Menu(); favoriteGroupsMenu = new Menu(); recentlyViewedMenu = new Menu(); favoriteResourcesMenu.setSubmenuDirection("left"); favoriteResourcesMenu.setAutoWidth(); favoriteGroupsMenu.setSubmenuDirection("left"); favoriteGroupsMenu.setAutoWidth(); recentlyViewedMenu.setSubmenuDirection("left"); recentlyViewedMenu.setAutoWidth(); MenuItem favoriteResourcesMenuItem = new MenuItem(MSG.favorites_resources(), "Favorite_Resource_16.png"); favoriteResourcesMenuItem.setSubmenu(favoriteResourcesMenu); favoriteResourcesMenu.setEmptyMessage(MSG.common_val_none()); MenuItem favoriteGroupsMenuItem = new MenuItem(MSG.favorites_groups(), "Favorite_Group_16.png"); favoriteGroupsMenuItem.setSubmenu(favoriteGroupsMenu); favoriteGroupsMenu.setEmptyMessage(MSG.common_val_none()); MenuItem recentlyViewedMenuItem = new MenuItem(MSG.favorites_recentlyViewed(), "global/Recent_16.png"); recentlyViewedMenuItem.setSubmenu(recentlyViewedMenu); recentlyViewedMenu.setEmptyMessage(MSG.common_val_none()); setItems(favoriteResourcesMenuItem, favoriteGroupsMenuItem, recentlyViewedMenuItem); } public void showMenu(int top, int left) { setTop(top); setLeft(left); final Set<Integer> favoriteResourceIds = UserSessionManager.getUserPreferences().getFavoriteResources(); final Set<Integer> favoriteGroupIds = UserSessionManager.getUserPreferences().getFavoriteResourceGroups(); final List<Integer> recentResourceIds = UserSessionManager.getUserPreferences().getRecentResources(); final List<Integer> recentGroupIds = UserSessionManager.getUserPreferences().getRecentResourceGroups(); // if we have no menu items at all, then show the empty menu now if (favoriteGroupIds.isEmpty() && favoriteResourceIds.isEmpty() && recentResourceIds.isEmpty() && recentGroupIds.isEmpty()) { FavoritesMenu.this.setVisible(true); return; } // keep a list of all the ids we need to pull from the db. combine favs and recents to minimize // db round trips. Set<Integer> resourceIds = new HashSet<Integer>(); Set<Integer> groupIds = new HashSet<Integer>(); resourceIds.addAll(favoriteResourceIds); resourceIds.addAll(recentResourceIds); groupIds.addAll(favoriteGroupIds); groupIds.addAll(recentGroupIds); fetchFavorites(resourceIds, groupIds, new AsyncCallback<Favorites>() { public void onFailure(Throwable caught) { CoreGUI.getErrorHandler().handleError(MSG.view_dashboard_favorites_error1(), caught); } public void onSuccess(final Favorites favorites) { // For Ancestry we need all the resource types and ancestry resource types loaded HashSet<Integer> typesSet = new HashSet<Integer>(); HashSet<String> ancestries = new HashSet<String>(); for (Resource resource : favorites.resources) { typesSet.add(resource.getResourceType().getId()); ancestries.add(resource.getAncestry()); } // In addition to the types of the result resources, get the types of their ancestry typesSet.addAll(AncestryUtil.getAncestryTypeIds(ancestries)); ResourceTypeRepository typeRepo = ResourceTypeRepository.Cache.getInstance(); typeRepo.getResourceTypes(typesSet.toArray(new Integer[typesSet.size()]), new TypesLoadedCallback() { @Override public void onTypesLoaded(Map<Integer, ResourceType> types) { // Smartgwt has issues storing a Map as a ListGridRecord attribute. Wrap it in a pojo. AncestryUtil.MapWrapper typesWrapper = new AncestryUtil.MapWrapper(types); // generate the menus buildFavoriteResourcesMenu(favorites, favoriteResourcesMenu, favoriteResourceIds, typesWrapper); buildFavoriteGroupsMenu(favorites, favoriteGroupsMenu, favoriteGroupIds); buildRecentlyViewedMenu(favorites, recentlyViewedMenu, recentResourceIds, recentGroupIds, typesWrapper); FavoritesMenu.this.setVisible(true); } }); } }); } private void buildFavoriteResourcesMenu(Favorites favorites, Menu menu, Set<Integer> resourceIds, AncestryUtil.MapWrapper typesWrapper) { if (resourceIds.isEmpty()) { menu.setItems(); return; } List<MenuItem> items = new ArrayList<MenuItem>(resourceIds.size()); for (final Integer resourceId : resourceIds) { Resource resource = favorites.getResource(resourceId); if (null == resource) { // if the resource is gone just skip it continue; } MenuItem item = new MenuItem(resource.getName()); item.setIcon(ImageManager.getResourceIcon(resource)); // build a subMenu to display a disambiguated resource item.setAttribute(AncestryUtil.RESOURCE_ID, resourceId); item.setAttribute(AncestryUtil.RESOURCE_NAME, resource.getName()); item.setAttribute(AncestryUtil.RESOURCE_ANCESTRY, resource.getAncestry()); item.setAttribute(AncestryUtil.RESOURCE_TYPE_ID, resource.getResourceType().getId()); item.setAttribute(AncestryUtil.RESOURCE_ANCESTRY_TYPES, typesWrapper); Menu ancestryMenu = new Menu(); MenuItem ancestryItem = new MenuItem(AncestryUtil.getAncestryHoverHTML(item, -1)); ancestryItem.setEnabled(false); ancestryMenu.setItems(ancestryItem); ancestryMenu.setSubmenuDirection("left"); ancestryMenu.setAutoWidth(); item.setSubmenu(ancestryMenu); item.addClickHandler(new com.smartgwt.client.widgets.menu.events.ClickHandler() { public void onClick(MenuItemClickEvent event) { CoreGUI.goToView(LinkManager.getResourceLink(resourceId)); } }); items.add(item); } menu.setCanSelectParentItems(Boolean.TRUE); menu.setItems(items.toArray(new MenuItem[items.size()])); } private void buildFavoriteGroupsMenu(Favorites favorites, Menu menu, Set<Integer> groupIds) { if (groupIds.isEmpty()) { menu.setItems(); return; } List<MenuItem> items = new ArrayList<MenuItem>(groupIds.size()); for (final Integer groupId : groupIds) { ResourceGroupComposite groupComposite = favorites.getGroupComposite(groupId); if (null == groupComposite) { // if the resource group is gone just skip it continue; } final ResourceGroup group = groupComposite.getResourceGroup(); MenuItem item = new MenuItem(String.valueOf(groupId)); item.setTitle(group.getName()); item.setIcon(ImageManager.getGroupIcon(group.getGroupCategory(), groupComposite.getExplicitAvailabilityType())); item.addClickHandler(new com.smartgwt.client.widgets.menu.events.ClickHandler() { public void onClick(MenuItemClickEvent event) { CoreGUI.goToView(LinkManager.getResourceGroupLink(group)); } }); items.add(item); } menu.setItems(items.toArray(new MenuItem[items.size()])); } private void buildRecentlyViewedMenu(Favorites favorites, Menu menu, List<Integer> recentResourceIds, List<Integer> recentGroupIds, AncestryUtil.MapWrapper typesWrapper) { if (recentResourceIds.isEmpty() && recentGroupIds.isEmpty()) { return; } List<MenuItem> items = new ArrayList<MenuItem>(recentResourceIds.size() + recentGroupIds.size() + 1); for (final Integer resourceId : recentResourceIds) { Resource resource = favorites.getResource(resourceId); if (null == resource) { // if the resource is gone just skip it continue; } MenuItem item = new MenuItem(resource.getName()); item.setIcon(ImageManager.getResourceIcon(resource)); // build a subMenu to display a disambiguated resource item.setAttribute(AncestryUtil.RESOURCE_ID, resourceId); item.setAttribute(AncestryUtil.RESOURCE_NAME, resource.getName()); item.setAttribute(AncestryUtil.RESOURCE_ANCESTRY, resource.getAncestry()); item.setAttribute(AncestryUtil.RESOURCE_TYPE_ID, resource.getResourceType().getId()); item.setAttribute(AncestryUtil.RESOURCE_ANCESTRY_TYPES, typesWrapper); Menu ancestryMenu = new Menu(); MenuItem ancestryItem = new MenuItem(AncestryUtil.getAncestryHoverHTML(item, -1)); ancestryItem.setEnabled(false); ancestryMenu.setItems(ancestryItem); ancestryMenu.setSubmenuDirection("left"); ancestryMenu.setAutoWidth(); item.setSubmenu(ancestryMenu); item.addClickHandler(new com.smartgwt.client.widgets.menu.events.ClickHandler() { public void onClick(MenuItemClickEvent event) { CoreGUI.goToView(LinkManager.getResourceLink(resourceId)); } }); items.add(item); } if (!recentResourceIds.isEmpty() && !recentGroupIds.isEmpty()) { items.add(new MenuItemSeparator()); } for (final Integer groupId : recentGroupIds) { ResourceGroupComposite groupComposite = favorites.getGroupComposite(groupId); if (null == groupComposite) { // if the resource group is gone just skip it continue; } final ResourceGroup group = groupComposite.getResourceGroup(); MenuItem item = new MenuItem(String.valueOf(groupId)); item.setTitle(group.getName()); item.setIcon(ImageManager.getGroupIcon(group.getGroupCategory(), groupComposite.getExplicitAvailabilityType())); item.addClickHandler(new com.smartgwt.client.widgets.menu.events.ClickHandler() { public void onClick(MenuItemClickEvent event) { CoreGUI.goToView(LinkManager.getResourceGroupLink(group)); } }); items.add(item); } menu.setCanSelectParentItems(Boolean.TRUE); menu.setItems(items.toArray(new MenuItem[items.size()])); } private void fetchFavorites(Set<Integer> resourceIds, final Set<Integer> groupIds, final AsyncCallback<Favorites> callback) { ResourceCriteria criteria = new ResourceCriteria(); criteria.addFilterIds(resourceIds.toArray(new Integer[resourceIds.size()])); GWTServiceLookup.getResourceService().findResourcesByCriteria(criteria, new AsyncCallback<PageList<Resource>>() { public void onFailure(Throwable caught) { callback.onFailure(caught); } public void onSuccess(final PageList<Resource> resources) { if (groupIds.isEmpty()) { callback.onSuccess(new Favorites(resources, new PageList<ResourceGroupComposite>())); return; } ResourceGroupCriteria criteria = new ResourceGroupCriteria(); criteria.addFilterIds(groupIds.toArray(new Integer[groupIds.size()])); GWTServiceLookup.getResourceGroupService().findResourceGroupCompositesByCriteria(criteria, new AsyncCallback<PageList<ResourceGroupComposite>>() { public void onFailure(Throwable caught) { callback.onFailure(caught); } public void onSuccess(PageList<ResourceGroupComposite> groups) { callback.onSuccess(new Favorites(resources, groups)); } }); } }); } private static class Favorites { private PageList<Resource> resources; private PageList<ResourceGroupComposite> groupComposites; public Favorites(PageList<Resource> resources, PageList<ResourceGroupComposite> groupComposites) { this.resources = resources; this.groupComposites = groupComposites; } public Resource getResource(int resourceId) { for (Resource resource : resources) { if (resourceId == resource.getId()) { return resource; } } return null; } public ResourceGroupComposite getGroupComposite(int groupId) { for (ResourceGroupComposite groupComposite : groupComposites) { if (groupId == groupComposite.getResourceGroup().getId()) { return groupComposite; } } return null; } } }