/* * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ package org.rhq.coregui.client.bundle.list; import static org.rhq.coregui.client.CoreGUI.getErrorHandler; import static org.rhq.coregui.client.CoreGUI.getMessageCenter; import static org.rhq.coregui.client.CoreGUI.goToView; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; import com.google.gwt.core.client.Duration; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.rpc.AsyncCallback; import com.smartgwt.client.data.Criteria; import com.smartgwt.client.data.Record; import com.smartgwt.client.types.Alignment; import com.smartgwt.client.types.ListGridFieldType; import com.smartgwt.client.widgets.events.DoubleClickEvent; import com.smartgwt.client.widgets.events.DoubleClickHandler; import com.smartgwt.client.widgets.grid.CellFormatter; import com.smartgwt.client.widgets.grid.ListGrid; import com.smartgwt.client.widgets.grid.ListGridField; import com.smartgwt.client.widgets.grid.ListGridRecord; import org.rhq.core.domain.authz.Permission; import org.rhq.core.domain.bundle.Bundle; import org.rhq.core.domain.bundle.composite.BundleWithLatestVersionComposite; import org.rhq.core.domain.criteria.BundleCriteria; import org.rhq.core.domain.util.PageList; import org.rhq.coregui.client.CoreGUI; import org.rhq.coregui.client.IconEnum; import org.rhq.coregui.client.LinkManager; import org.rhq.coregui.client.bundle.create.BundleCreateWizard; import org.rhq.coregui.client.bundle.deploy.BundleDeployWizard; import org.rhq.coregui.client.components.table.BundleAuthorizedTableAction; import org.rhq.coregui.client.components.table.RecordExtractor; import org.rhq.coregui.client.components.table.RoleAuthorizedTableAction; import org.rhq.coregui.client.components.table.Table; import org.rhq.coregui.client.components.table.TableActionEnablement; import org.rhq.coregui.client.gwt.GWTServiceLookup; import org.rhq.coregui.client.util.ErrorHandler; import org.rhq.coregui.client.util.StringUtility; import org.rhq.coregui.client.util.enhanced.EnhancedIButton.ButtonColor; import org.rhq.coregui.client.util.message.Message; import org.rhq.coregui.client.util.message.Message.Severity; /** * Shows a list of bundles in the system. The list gives you some actions like new, delete and deploy but * only if you provide the proper permissions. If you give null permissions, no action buttons are shown. * * @author Greg Hinkle * @author John Mazzitelli */ public class BundlesListView extends Table<BundlesWithLatestVersionDataSource> { private final Set<Permission> globalPermissions; /** * Creates a new list view. * * @param perms if perms is null, no button actions will be shown in the table */ public BundlesListView(Set<Permission> perms) { this(null, perms); } public BundlesListView(Criteria criteria, Set<Permission> perms) { super(MSG.common_title_bundles(), criteria, IconEnum.BUNDLE.getIcon24x24Path()); globalPermissions = perms; setDataSource(new BundlesWithLatestVersionDataSource()); } @Override protected void configureTable() { ListGridField idField = new ListGridField(BundlesWithLatestVersionDataSource.FIELD_ID, MSG.common_title_id()); idField.setType(ListGridFieldType.INTEGER); idField.setWidth("50"); ListGridField nameField = new ListGridField(BundlesWithLatestVersionDataSource.FIELD_NAME, MSG.common_title_name()); nameField.setWidth("33%"); nameField.setCellFormatter(new CellFormatter() { @Override public String format(Object value, ListGridRecord record, int i, int i1) { return "<a href=\"" + record.getAttribute(BundlesWithLatestVersionDataSource.FIELD_NAMELINK) + "\">" + StringUtility.escapeHtml(String.valueOf(value)) + "</a>"; } }); ListGridField descField = new ListGridField(BundlesWithLatestVersionDataSource.FIELD_DESCRIPTION, MSG.common_title_description()); descField.setWidth("33%"); descField.setCellFormatter(new CellFormatter() { @Override public String format(Object value, ListGridRecord record, int i, int i1) { return StringUtility.escapeHtml(String.valueOf(value)); } }); ListGridField latestVersionField = new ListGridField(BundlesWithLatestVersionDataSource.FIELD_LATEST_VERSION, MSG.view_bundle_latestVersion()); latestVersionField.setWidth("20%"); latestVersionField.setAlign(Alignment.CENTER); ListGridField versionsCountField = new ListGridField(BundlesWithLatestVersionDataSource.FIELD_VERSIONS_COUNT, MSG.view_bundle_list_versionsCount()); versionsCountField.setType(ListGridFieldType.INTEGER); versionsCountField.setWidth("*"); versionsCountField.setAlign(Alignment.CENTER); setListGridFields(idField, nameField, descField, latestVersionField, versionsCountField); setListGridDoubleClickHandler(new DoubleClickHandler() { @Override public void onDoubleClick(DoubleClickEvent event) { ListGrid listGrid = (ListGrid) event.getSource(); ListGridRecord[] selectedRows = listGrid.getSelectedRecords(); if (selectedRows != null && selectedRows.length == 1) { String selectedId = selectedRows[0].getAttribute(BundlesWithLatestVersionDataSource.FIELD_ID); goToView(LinkManager.getBundleLink(Integer.valueOf(selectedId))); } } }); // only show the buttons if we were given a set of permissions - passing in null is a way to say you only want the list, no actions if (globalPermissions != null) { boolean hasGlobalDelete = globalPermissions.contains(Permission.DELETE_BUNDLES); addTableAction(MSG.common_button_new(), null, ButtonColor.BLUE, new RoleAuthorizedTableAction( BundlesListView.this, Permission.CREATE_BUNDLES, Permission.CREATE_BUNDLES_IN_GROUP) { @Override public void executeAction(ListGridRecord[] selection, Object actionValue) { new BundleCreateWizard(globalPermissions).startWizard(); // we can refresh the table buttons immediately since the wizard is a dialog, the // user can't access enabled buttons anyway. BundlesListView.this.refreshTableInfo(); } }); addTableAction(MSG.common_button_delete(), MSG.view_bundle_list_deleteConfirm(), ButtonColor.RED, new DeleteBundleTableAction(this, getDataSource(), hasGlobalDelete)); addTableAction(MSG.view_bundle_deploy(), null, ButtonColor.GRAY, new DeployBundleTableAction(this, getDataSource())); } } private static class DeleteBundleTableAction extends BundleAuthorizedTableAction { final BundlesListView view; final BundlesWithLatestVersionDataSource dataSource; DeleteBundleTableAction(BundlesListView view, BundlesWithLatestVersionDataSource dataSource, boolean hasGlobalDelete) { super(view, TableActionEnablement.ANY, (hasGlobalDelete ? null : Permission.DELETE_BUNDLES_FROM_GROUP), new RecordIdExtractor()); this.view = view; this.dataSource = dataSource; } @Override public void executeAction(ListGridRecord[] selections, Object actionValue) { if (selections == null || selections.length == 0) { return; } getMessageCenter().notify(new Message(MSG.view_bundle_list_deleteSubmitted(), Severity.Info)); final ArrayList<String> doomedNames = new ArrayList<String>(selections.length); int[] doomedIds = new int[selections.length]; int i = 0; for (ListGridRecord selection : selections) { BundleWithLatestVersionComposite object = dataSource.copyValues(selection); doomedNames.add(object.getBundleName()); doomedIds[i++] = object.getBundleId(); } final Duration duration = new Duration(); GWTServiceLookup.getBundleService().deleteBundles(doomedIds, new AsyncCallback<Void>() { @Override public void onFailure(final Throwable caught) { Timer timer = new Timer() { @Override public void run() { String conciseMessage = MSG.view_bundle_list_deletesFailure(); String detailedMessage = doomedNames.toString() + "<br/>\n" + ErrorHandler.getAllMessages(caught); getMessageCenter().notify(new Message(conciseMessage, detailedMessage, Severity.Error)); } }; // Delay the showing of the result to give the user some time to see the deleteSubmitted notif timer.schedule(Math.max(0, 3 * 1000 - duration.elapsedMillis())); } @Override public void onSuccess(Void result) { Timer timer = new Timer() { @Override public void run() { String conciseMessage = MSG.view_bundle_list_deletesSuccessful(); String detailedMessage = doomedNames.toString(); getMessageCenter().notify(new Message(conciseMessage, detailedMessage, Severity.Info)); CoreGUI.refresh(); } }; // Delay the showing of the result to give the user some time to see the deleteSubmitted notif timer.schedule(Math.max(0, 3 * 1000 - duration.elapsedMillis())); } }); } } private static class RecordIdExtractor implements RecordExtractor<Integer> { @Override public Collection<Integer> extract(Record[] records) { List<Integer> result = new ArrayList<Integer>(records.length); for (Record record : records) { result.add(record.getAttributeAsInt("id")); } return result; } } private static class DeployBundleTableAction extends RoleAuthorizedTableAction { final BundlesListView view; final BundlesWithLatestVersionDataSource dataSource; DeployBundleTableAction(BundlesListView view, BundlesWithLatestVersionDataSource dataSource) { super(view, TableActionEnablement.SINGLE, Permission.DEPLOY_BUNDLES, Permission.DEPLOY_BUNDLES_TO_GROUP); this.view = view; this.dataSource = dataSource; } @Override public void executeAction(ListGridRecord[] selection, Object actionValue) { final BundleWithLatestVersionComposite object = dataSource.copyValues(selection[0]); BundleCriteria bc = new BundleCriteria(); bc.addFilterId(object.getBundleId()); GWTServiceLookup.getBundleService().findBundlesByCriteria(bc, new AsyncCallback<PageList<Bundle>>() { @Override public void onFailure(Throwable caught) { getErrorHandler().handleError(MSG.view_bundle_list_loadFailure(object.getBundleName()), caught); } @Override public void onSuccess(PageList<Bundle> result) { if (result == null || result.size() != 1) { String message = MSG.view_bundle_list_singleLoadFailure(object.getBundleName()); getMessageCenter().notify(new Message(message, Severity.Error)); return; } new BundleDeployWizard(result.get(0)).startWizard(); // we can refresh the table buttons immediately since the wizard is a dialog, the // user can't access enabled buttons anyway. view.refreshTableInfo(); } }); } } }