/* * RHQ Management Platform * Copyright (C) 2005-2011 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, version 2, as * published by the Free Software Foundation, and/or the GNU Lesser * General Public License, version 2.1, also as published by the Free * Software Foundation. * * 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 and the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU General Public License * and the GNU Lesser General Public License along with this program; * if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.rhq.coregui.client.inventory.groups.detail; import java.util.EnumSet; import java.util.HashMap; import java.util.Map; import java.util.TreeSet; import com.google.gwt.user.client.rpc.AsyncCallback; import com.smartgwt.client.widgets.layout.VLayout; 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.ClickHandler; import com.smartgwt.client.widgets.menu.events.MenuItemClickEvent; import com.smartgwt.client.widgets.tree.TreeGrid; import com.smartgwt.client.widgets.tree.TreeNode; import org.rhq.core.domain.common.EntityContext; import org.rhq.core.domain.criteria.ResourceGroupCriteria; import org.rhq.core.domain.operation.OperationDefinition; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.domain.resource.group.GroupCategory; 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.core.domain.util.ResourceTypeUtility; import org.rhq.coregui.client.CoreGUI; 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.detail.ResourceDetailView; import org.rhq.coregui.client.inventory.resource.detail.ResourceTreeDatasource.AutoGroupTreeNode; import org.rhq.coregui.client.inventory.resource.detail.ResourceTreeView; import org.rhq.coregui.client.inventory.resource.type.ResourceTypeRepository; import org.rhq.coregui.client.util.preferences.UserPreferenceNames.UiSubsystem; /** * @author Jay Shaughnessy * @author Greg Hinkle */ public class ResourceGroupContextMenu extends Menu { protected Messages MSG = CoreGUI.getMessages(); private ResourceGroupComposite groupComposite; private ResourceGroup group; private ResourceType groupMemberType; private boolean isAutoCluster = false; private boolean isAutoGroup = false; public void showContextMenu(final VLayout treeView, final TreeGrid treeGrid, final TreeNode node, final ResourceGroup group) { // we need the group composite to access permissions for context menu authz, so get it now ResourceGroupCriteria criteria = new ResourceGroupCriteria(); criteria.addFilterId(group.getId()); // for autoclusters and private groups (autogroups) we need to add more criteria isAutoCluster = (null != group.getClusterResourceGroup()); isAutoGroup = (null != group.getSubject()); if (isAutoCluster) { criteria.addFilterVisible(false); } else if (isAutoGroup) { criteria.addFilterVisible(false); criteria.addFilterPrivate(true); } GWTServiceLookup.getResourceGroupService().findResourceGroupCompositesByCriteria(criteria, new AsyncCallback<PageList<ResourceGroupComposite>>() { public void onFailure(Throwable caught) { CoreGUI.getErrorHandler().handleError( MSG.view_group_detail_failLoadComp(String.valueOf(group.getId())), caught); } public void onSuccess(PageList<ResourceGroupComposite> result) { if (result.isEmpty()) { CoreGUI.getErrorHandler().handleError( MSG.view_group_detail_failLoadComp(String.valueOf(group.getId()))); } else { showContextMenu(treeView, treeGrid, node, result.get(0)); } } }); } public void showContextMenu(final VLayout treeView, final TreeGrid treeGrid, final TreeNode node, ResourceGroupComposite groupComposite) { this.groupComposite = groupComposite; group = groupComposite.getResourceGroup(); // [BZ 817604] If the group type has changed to mixed we can't show a context menu. if (GroupCategory.MIXED == group.getGroupCategory()) { CoreGUI.goToView(LinkManager.getResourceGroupLink(group.getId())); return; } groupMemberType = group.getResourceType(); isAutoCluster = (null != group.getClusterResourceGroup()); isAutoGroup = (null != group.getSubject()); ResourceTypeRepository.Cache.getInstance().getResourceTypes( groupMemberType.getId(), EnumSet.of(ResourceTypeRepository.MetadataType.operations, ResourceTypeRepository.MetadataType.children, ResourceTypeRepository.MetadataType.pluginConfigurationDefinition, ResourceTypeRepository.MetadataType.resourceConfigurationDefinition), new ResourceTypeRepository.TypeLoadedCallback() { public void onTypesLoaded(ResourceType type) { groupMemberType = type; buildResourceGroupContextMenu(treeView, treeGrid, node, group, type); showContextMenu(); } }); } private void buildResourceGroupContextMenu(final VLayout treeView, final TreeGrid treeGrid, final TreeNode node, final ResourceGroup group, final ResourceType resourceType) { // name setItems(new MenuItem(group.getName())); // type name addItem(new MenuItem("Type: " + ResourceTypeUtility.displayName(resourceType))); // Mixed group refresh is not needed as there is only a single top node. Compat group // refresh makes sense after a group membership change but we already perform a CoreGUI refresh to // reset the whole detail view after that user action. So, only support refresh for autogroup nodes // in the resource tree. if (node instanceof AutoGroupTreeNode) { // separator addItem(new MenuItemSeparator()); // refresh node MenuItem refresh = new MenuItem(MSG.common_button_refresh()); refresh.addClickHandler(new ClickHandler() { public void onClick(MenuItemClickEvent event) { // refresh the tree and detail ((ResourceTreeView) treeView).contextMenuRefresh(treeGrid, node, false); } }); addItem(refresh); } // separator addItem(new MenuItemSeparator()); // plugin config MenuItem pluginConfiguration = new MenuItem(MSG.view_tabs_common_connectionSettings()); boolean pluginConfigEnabled = resourceType.getPluginConfigurationDefinition() != null; pluginConfiguration.setEnabled(pluginConfigEnabled); if (pluginConfigEnabled) { pluginConfiguration.addClickHandler(new ClickHandler() { public void onClick(MenuItemClickEvent event) { CoreGUI.goToView(LinkManager.getEntityTabLink(EntityContext.forGroup(group), "Inventory", "ConnectionSettings")); } }); } addItem(pluginConfiguration); Map<UiSubsystem, Boolean> showSubsystems = UserSessionManager.getUserPreferences().getShowUiSubsystems(); // resource config if (showSubsystems.get(UiSubsystem.CONFIG)) { MenuItem resourceConfiguration = new MenuItem(MSG.view_tree_common_contextMenu_resourceConfiguration()); boolean resourceConfigEnabled = groupComposite.getResourcePermission().isConfigureRead() && resourceType.getResourceConfigurationDefinition() != null; resourceConfiguration.setEnabled(resourceConfigEnabled); if (resourceConfigEnabled) { resourceConfiguration.addClickHandler(new ClickHandler() { public void onClick(MenuItemClickEvent event) { CoreGUI.goToView(LinkManager.getEntityTabLink(EntityContext.forGroup(group), "Configuration", "Current")); } }); } addItem(resourceConfiguration); } // separator addItem(new MenuItemSeparator()); // Operations Menu if (showSubsystems.get(UiSubsystem.OPERATIONS)) { MenuItem operations = new MenuItem(MSG.common_title_operations()); boolean operationsEnabled = (groupComposite.getResourcePermission().isControl() && null != resourceType.getOperationDefinitions() && !resourceType.getOperationDefinitions().isEmpty()); operations.setEnabled(operationsEnabled); if (operationsEnabled) { Menu opSubMenu = new Menu(); //sort the display items alphabetically TreeSet<String> ordered = new TreeSet<String>(); Map<String, OperationDefinition> definitionMap = new HashMap<String, OperationDefinition>(); for (OperationDefinition o : resourceType.getOperationDefinitions()) { ordered.add(o.getDisplayName()); definitionMap.put(o.getDisplayName(), o); } for (String displayName : ordered) { final OperationDefinition operationDefinition = definitionMap.get(displayName); MenuItem operationItem = new MenuItem(operationDefinition.getDisplayName()); operationItem.addClickHandler(new ClickHandler() { public void onClick(MenuItemClickEvent event) { String viewPath = LinkManager.getEntityTabLink(EntityContext.forGroup(group), ResourceDetailView.Tab.Operations.NAME, "Schedules") + "/0/" + operationDefinition.getId(); CoreGUI.goToView(viewPath); } }); opSubMenu.addItem(operationItem); } operations.setSubmenu(opSubMenu); } addItem(operations); } } }