/*
* RHQ Management Platform
* Copyright (C) 2010 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.inventory.groups.detail.summary;
import java.util.Map;
import java.util.Set;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.util.BooleanCallback;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.IButton;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.common.EntityContext;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.criteria.DashboardCriteria;
import org.rhq.core.domain.dashboard.Dashboard;
import org.rhq.core.domain.dashboard.DashboardCategory;
import org.rhq.core.domain.dashboard.DashboardPortlet;
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.InitializableView;
import org.rhq.coregui.client.PermissionsLoadedListener;
import org.rhq.coregui.client.PermissionsLoader;
import org.rhq.coregui.client.UserSessionManager;
import org.rhq.coregui.client.dashboard.DashboardContainer;
import org.rhq.coregui.client.dashboard.DashboardView;
import org.rhq.coregui.client.dashboard.portlets.groups.GroupAlertsPortlet;
import org.rhq.coregui.client.dashboard.portlets.groups.GroupConfigurationUpdatesPortlet;
import org.rhq.coregui.client.dashboard.portlets.groups.GroupEventsPortlet;
import org.rhq.coregui.client.dashboard.portlets.groups.GroupMetricsPortlet;
import org.rhq.coregui.client.dashboard.portlets.groups.GroupOperationsPortlet;
import org.rhq.coregui.client.gwt.DashboardGWTServiceAsync;
import org.rhq.coregui.client.gwt.GWTServiceLookup;
import org.rhq.coregui.client.util.enhanced.EnhancedIButton;
import org.rhq.coregui.client.util.enhanced.EnhancedToolStrip;
import org.rhq.coregui.client.util.enhanced.EnhancedVLayout;
/**
* The content pane for the group Summary>Activity subtab.
*
* @author Simeon Pinder
* @author Jay Shaughnessy
*/
public class ActivityView extends EnhancedVLayout implements DashboardContainer, InitializableView {
private static final String DASHBOARD_NAME_PREFIX = "GroupDashboard_";
private ResourceGroupComposite groupComposite;
private boolean isAutoGroup;
private boolean isAutoCluster;
private DashboardGWTServiceAsync dashboardService = GWTServiceLookup.getDashboardService();
private DashboardView dashboardView;
private EnhancedToolStrip footer;
private IButton editButton;
private IButton resetButton;
// Capture the user's global permissions for use by any dashboard or portlet that may need it for rendering.
private Set<Permission> globalPermissions;
private boolean editMode = false;
private boolean isInitialized = false;
//default portlet positioning parameters
private int colLeft = 0;
private int colRight = 1;
private int rowLeft = 0;
private int rowRight = 0;
private boolean displayLeft = false;
public ActivityView(ResourceGroupComposite groupComposite, boolean isAutoCluster, boolean isAutoGroup) {
super();
this.groupComposite = groupComposite;
this.isAutoCluster = isAutoCluster;
this.isAutoGroup = isAutoGroup;
}
@Override
protected void onInit() {
if (!isInitialized()) {
super.onInit();
// first async call to get global permissions
new PermissionsLoader().loadExplicitGlobalPermissions(new PermissionsLoadedListener() {
public void onPermissionsLoaded(Set<Permission> permissions) {
globalPermissions = permissions;
// now make async call to look for customized dash for this user and entity
DashboardCriteria criteria = new DashboardCriteria();
criteria.addFilterCategory(DashboardCategory.GROUP);
criteria.addFilterGroupId(groupComposite.getResourceGroup().getId());
dashboardService.findDashboardsByCriteria(criteria, new AsyncCallback<PageList<Dashboard>>() {
public void onFailure(Throwable caught) {
CoreGUI.getErrorHandler().handleError(MSG.view_dashboardsManager_error1(), caught);
}
public void onSuccess(final PageList<Dashboard> result) {
Dashboard dashboard = result.isEmpty() ? getDefaultDashboard() : result.get(0);
setDashboard(dashboard);
isInitialized = true;
// draw() may be done since onInit finishes asynchronously, if so redraw
if (isDrawn()) {
markForRedraw();
}
}
});
}
});
}
}
private void setDashboard(Dashboard dashboard) {
Canvas[] members = getMembers();
removeMembers(members);
//pass in the group information
EntityContext context = EntityContext.forGroup(groupComposite.getResourceGroup().getId(), isAutoCluster,
isAutoGroup);
dashboardView = new DashboardView(this, dashboard, context, groupComposite);
addMember(dashboardView);
footer = new EnhancedToolStrip();
footer.setPadding(5);
footer.setWidth100();
footer.setMembersMargin(15);
editButton = new EnhancedIButton(editMode ? MSG.common_title_view_mode() : MSG.common_title_edit_mode());
editButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent clickEvent) {
editMode = !editMode;
editButton.setTitle(editMode ? MSG.common_title_view_mode() : MSG.common_title_edit_mode());
dashboardView.setEditMode(editMode);
}
});
resetButton = new EnhancedIButton(MSG.common_button_reset());
resetButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent clickEvent) {
String message = MSG.view_summaryDashboard_resetConfirm();
SC.ask(message, new BooleanCallback() {
public void execute(Boolean confirmed) {
if (confirmed) {
dashboardView.delete();
setDashboard(getDefaultDashboard());
markForRedraw();
}
}
});
}
});
footer.addMember(editButton);
footer.addMember(resetButton);
addMember(footer);
}
protected Dashboard getDefaultDashboard() {
Subject sessionSubject = UserSessionManager.getSessionSubject();
final ResourceGroup group = groupComposite.getResourceGroup();
final Dashboard dashboard = new Dashboard();
dashboard.setName(DASHBOARD_NAME_PREFIX + sessionSubject.getId() + "_" + group.getId());
dashboard.setCategory(DashboardCategory.GROUP);
dashboard.setGroup(group);
dashboard.setColumns(2);
// set leftmost column and let the rest be equally divided
dashboard.setColumnWidths("40%");
dashboard.getConfiguration().put(new PropertySimple(Dashboard.CFG_BACKGROUND, "transparent"));
//figure out which portlets to display and how
Map<String, String> groupKeyNameMap = DashboardView.processPortletNameMapForGroup(groupComposite);
//reset positioning parameters
colLeft = 0;
colRight = 1;
rowLeft = 0;
rowRight = 0;
//Left Column
if (groupKeyNameMap.containsKey(GroupMetricsPortlet.KEY)) {//measurments top left if available
DashboardPortlet measurements = new DashboardPortlet(GroupMetricsPortlet.NAME, GroupMetricsPortlet.KEY, 220);
dashboard.addPortlet(measurements, colLeft, rowLeft++);
groupKeyNameMap.remove(GroupMetricsPortlet.KEY);
}
// right Column(approx 60%. As larger more room to display table and N rows.)
if (groupKeyNameMap.containsKey(GroupAlertsPortlet.KEY)) {//alerts top right if available
DashboardPortlet alerts = new DashboardPortlet(GroupAlertsPortlet.NAME, GroupAlertsPortlet.KEY, 210);
dashboard.addPortlet(alerts, colRight, rowRight++);
groupKeyNameMap.remove(GroupAlertsPortlet.KEY);
}
if (groupKeyNameMap.containsKey(GroupEventsPortlet.KEY)) {//events if available
DashboardPortlet events = new DashboardPortlet(GroupEventsPortlet.NAME, GroupEventsPortlet.KEY, 210);
dashboard.addPortlet(events, colRight, rowRight++);
groupKeyNameMap.remove(GroupEventsPortlet.KEY);
}
if (groupKeyNameMap.containsKey(GroupOperationsPortlet.KEY)) {//operations if available
DashboardPortlet ops = new DashboardPortlet(GroupOperationsPortlet.NAME, GroupOperationsPortlet.KEY, 210);
dashboard.addPortlet(ops, colRight, rowRight++);
groupKeyNameMap.remove(GroupOperationsPortlet.KEY);
}
if (groupKeyNameMap.containsKey(GroupConfigurationUpdatesPortlet.KEY)) {//operations if available
DashboardPortlet ops = new DashboardPortlet(GroupConfigurationUpdatesPortlet.NAME,
GroupConfigurationUpdatesPortlet.KEY, 210);
dashboard.addPortlet(ops, colRight, rowRight++);
groupKeyNameMap.remove(GroupConfigurationUpdatesPortlet.KEY);
}
//Fill out left column(typically smaller portlets) then alternate cols with remaining
displayLeft = false;
updateDashboardWithPortlets(groupKeyNameMap, dashboard, 105);
return dashboard;
}
/**Iterates list of new portlets and updates the dashboard reference with these new portlets.
* Attempts to fill the spaces around the remaining larger portlets if already installed, then alternates
* adding to left and right columns. Assumes dashboard has only two columns.
*
* @param keyNameMap portlet key|name map
* @param dashboard dasboard instance to update
*/
private void updateDashboardWithPortlets(Map<String, String> keyNameMap, Dashboard dashboard, int initialHeight) {
if ((keyNameMap != null) && (dashboard != null)) {
for (String key : keyNameMap.keySet()) {
//locate portlet and add to dashboard
DashboardPortlet portlet = new DashboardPortlet(keyNameMap.get(key), key, initialHeight);
if (rowLeft < 4) {
dashboard.addPortlet(portlet, colLeft, rowLeft++);
} else {//alternate
if (!displayLeft) {
dashboard.addPortlet(portlet, colRight, rowRight++);
} else {
dashboard.addPortlet(portlet, colLeft, rowLeft++);
}
//toggle
displayLeft = !displayLeft;
}
}
}
}
@Override
public boolean isInitialized() {
return isInitialized;
}
public Set<Permission> getGlobalPermissions() {
return globalPermissions;
}
/**
* name update not supported because the name is derived from the entity id.
* @return
*/
public boolean supportsDashboardNameEdit() {
return false;
}
public void updateDashboardNames() {
return;
}
@Override
public boolean isValidDashboardName(String name) {
return ((name != null) && (dashboardView != null) && name.equals(dashboardView.getDashboard().getName()));
}
@Override
public void refresh() {
if (isInitialized()) {
dashboardView.rebuild();
}
}
}