/* * RHQ Management Platform * Copyright (C) 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.drift; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.Set; import com.google.gwt.user.client.rpc.AsyncCallback; import com.smartgwt.client.data.DSRequest; import com.smartgwt.client.data.DSResponse; import com.smartgwt.client.data.Record; import com.smartgwt.client.rpc.RPCResponse; import com.smartgwt.client.types.Alignment; import com.smartgwt.client.types.ListGridFieldType; import com.smartgwt.client.widgets.grid.CellFormatter; import com.smartgwt.client.widgets.grid.HoverCustomizer; import com.smartgwt.client.widgets.grid.ListGridField; import com.smartgwt.client.widgets.grid.ListGridRecord; import com.smartgwt.client.widgets.grid.events.RecordClickEvent; import com.smartgwt.client.widgets.grid.events.RecordClickHandler; import org.rhq.core.domain.authz.Permission; import org.rhq.core.domain.common.EntityContext; import org.rhq.core.domain.criteria.DriftDefinitionCriteria; import org.rhq.core.domain.drift.DriftChangeSet; import org.rhq.core.domain.drift.DriftComplianceStatus; import org.rhq.core.domain.drift.DriftConfigurationDefinition.DriftHandlingMode; import org.rhq.core.domain.drift.DriftDefinition; import org.rhq.core.domain.drift.DriftDefinition.BaseDirectory; import org.rhq.core.domain.drift.DriftDefinitionComposite; import org.rhq.core.domain.util.PageControl; 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.PermissionsLoadedListener; import org.rhq.coregui.client.PermissionsLoader; import org.rhq.coregui.client.components.table.TimestampCellFormatter; import org.rhq.coregui.client.gwt.DriftGWTServiceAsync; import org.rhq.coregui.client.gwt.GWTServiceLookup; import org.rhq.coregui.client.inventory.resource.AncestryUtil; import org.rhq.coregui.client.util.RPCDataSource; /** * @author Jay Shaughnessy * @author John Mazzitelli */ public class DriftDefinitionDataSource extends RPCDataSource<DriftDefinitionComposite, DriftDefinitionCriteria> { public static final String ATTR_ENTITY = "object"; public static final String ATTR_ID = "id"; public static final String ATTR_NAME = "name"; public static final String ATTR_DESCRIPTION = "description"; public static final String ATTR_INTERVAL = "interval"; public static final String ATTR_DRIFT_HANDLING_MODE = "driftHandlingMode"; public static final String ATTR_BASE_DIR_STRING = "baseDirString"; public static final String ATTR_IS_ENABLED = "isEnabled"; public static final String ATTR_IS_ENABLED_ICON = "isEnabledIcon"; public static final String ATTR_EDIT = "edit"; public static final String ATTR_IS_PINNED = "isPinned"; public static final String ATTR_CHANGE_SET_CTIME = "changesetTime"; public static final String ATTR_CHANGE_SET_VERSION = "changesetVersion"; public static final String ATTR_COMPLIANCE = "compliance"; public static final String ATTR_COMPLIANCE_ICON = "complianceIcon"; public static final String ATTR_ATTACHED = "attached"; public static final String ATTR_TEMPLATE = "template"; public static final String DRIFT_HANDLING_MODE_NORMAL = MSG.view_drift_table_driftHandlingMode_normal(); public static final String DRIFT_HANDLING_MODE_PLANNED = MSG.view_drift_table_driftHandlingMode_plannedChanges(); private DriftGWTServiceAsync driftService = GWTServiceLookup.getDriftService(); private EntityContext entityContext; private Set<Permission> globalPermissions; private boolean hasWriteAccess; public DriftDefinitionDataSource() { this(EntityContext.forSubsystemView()); } public DriftDefinitionDataSource(EntityContext context) { this.entityContext = context; addDataSourceFields(); } /** * The view that contains the list grid which will display this datasource's data will call this * method to get the field information which is used to control the display of the data. * * @return list grid fields used to display the datasource data */ public ArrayList<ListGridField> getListGridFields(final boolean hasWriteAccess) { this.hasWriteAccess = hasWriteAccess; ArrayList<ListGridField> fields = new ArrayList<ListGridField>(6); ListGridField nameField = new ListGridField(ATTR_NAME, MSG.common_title_name()); fields.add(nameField); ListGridField pinnedField = new ListGridField(ATTR_IS_PINNED, MSG.view_drift_table_pinned()); pinnedField.setType(ListGridFieldType.IMAGE); pinnedField.setAlign(Alignment.CENTER); pinnedField.addRecordClickHandler(new RecordClickHandler() { public void onRecordClick(RecordClickEvent event) { switch (entityContext.getType()) { case Resource: CoreGUI.goToView(LinkManager.getDriftDefinitionInitialSnapshotLink(entityContext.getResourceId(), event.getRecord().getAttributeAsInt(ATTR_ID))); break; default: throw new IllegalArgumentException("Entity Type not supported"); } } }); pinnedField.setShowHover(true); pinnedField.setHoverCustomizer(new HoverCustomizer() { public String hoverHTML(Object value, ListGridRecord record, int rowNum, int colNum) { return ImageManager.getPinnedIcon().equals(record.getAttribute(ATTR_IS_PINNED)) ? MSG .view_drift_table_hover_defPinned() : MSG.view_drift_table_hover_defNotPinned(); } }); fields.add(pinnedField); ListGridField changeSetField = new ListGridField(ATTR_CHANGE_SET_VERSION, MSG.view_drift_table_snapshot()); changeSetField.setCanSortClientOnly(true); fields.add(changeSetField); ListGridField changeSetTimeField = new ListGridField(ATTR_CHANGE_SET_CTIME, MSG.view_drift_table_snapshotTime()); changeSetTimeField.setCellFormatter(new TimestampCellFormatter()); changeSetTimeField.setShowHover(true); changeSetTimeField.setHoverCustomizer(TimestampCellFormatter.getHoverCustomizer(ATTR_CHANGE_SET_CTIME)); changeSetTimeField.setCanSortClientOnly(true); fields.add(changeSetTimeField); ListGridField enabledField = new ListGridField(ATTR_IS_ENABLED_ICON, MSG.common_title_enabled()); enabledField.setType(ListGridFieldType.IMAGE); enabledField.setAlign(Alignment.CENTER); fields.add(enabledField); ListGridField inComplianceField = new ListGridField(ATTR_COMPLIANCE_ICON, MSG.common_title_in_compliance()); inComplianceField.setType(ListGridFieldType.IMAGE); inComplianceField.setAlign(Alignment.CENTER); inComplianceField.setShowHover(true); inComplianceField.setHoverCustomizer(new HoverCustomizer() { @Override public String hoverHTML(Object o, ListGridRecord record, int row, int column) { int complianceCode = record.getAttributeAsInt(ATTR_COMPLIANCE); DriftComplianceStatus complianceStatus = DriftComplianceStatus.fromCode(complianceCode); switch (complianceStatus) { case OUT_OF_COMPLIANCE_NO_BASEDIR: return MSG.view_drift_table_hover_outOfCompliance_noBaseDir(); case OUT_OF_COMPLIANCE_DRIFT: return MSG.view_drift_table_hover_outOfCompliance_drift(); default: return ""; } } }); fields.add(inComplianceField); /* ListGridField driftHandlingModeField = new ListGridField(ATTR_DRIFT_HANDLING_MODE, MSG .view_drift_table_driftHandlingMode()); fields.add(driftHandlingModeField); */ /* ListGridField intervalField = new ListGridField(ATTR_INTERVAL, MSG.common_title_interval()); fields.add(intervalField); */ ListGridField baseDirField = new ListGridField(ATTR_BASE_DIR_STRING, MSG.view_drift_table_baseDir()); changeSetTimeField.setCanSortClientOnly(true); fields.add(baseDirField); ListGridField attachedField = new ListGridField(ATTR_ATTACHED, MSG.view_drift_table_attached()); fields.add(attachedField); ListGridField templateField = new ListGridField(ATTR_TEMPLATE, MSG.view_drift_table_template()); templateField.setCellFormatter(new CellFormatter() { public String format(Object o, ListGridRecord listGridRecord, int i, int i1) { DriftDefinition def = (DriftDefinition) listGridRecord.getAttributeAsObject(ATTR_ENTITY); if (null == def.getTemplate()) { return MSG.common_val_none(); } if (null != globalPermissions && globalPermissions.contains(Permission.MANAGE_SETTINGS)) { int typeId = def.getResource().getResourceType().getId(); int templateId = def.getTemplate().getId(); String link = LinkManager.getDriftTemplateLink(typeId, templateId); return LinkManager.getHref(link, o.toString()); } else { return o.toString(); } } }); templateField.setCanSortClientOnly(true); fields.add(templateField); ListGridField editField = new ListGridField(ATTR_EDIT, hasWriteAccess ? MSG.common_title_edit() : MSG.common_title_view_mode()); editField.setType(ListGridFieldType.IMAGE); editField.setAlign(Alignment.CENTER); editField.setShowHover(true); editField.setCanSort(false); editField.addRecordClickHandler(new RecordClickHandler() { public void onRecordClick(RecordClickEvent event) { switch (entityContext.getType()) { case Resource: CoreGUI.goToView(LinkManager.getDriftDefinitionEditLink(entityContext.getResourceId(), event .getRecord().getAttributeAsInt(ATTR_ID))); break; default: throw new IllegalArgumentException("Entity Type not supported"); } } }); editField.setHoverCustomizer(new HoverCustomizer() { public String hoverHTML(Object value, ListGridRecord record, int rowNum, int colNum) { return MSG.view_drift_table_hover_edit(); } }); fields.add(editField); if (this.entityContext.type != EntityContext.Type.Resource) { ListGridField resourceNameField = new ListGridField(AncestryUtil.RESOURCE_NAME, MSG.common_title_resource()); resourceNameField.setCellFormatter(new CellFormatter() { public String format(Object o, ListGridRecord listGridRecord, int i, int i1) { Integer resourceId = listGridRecord.getAttributeAsInt(AncestryUtil.RESOURCE_ID); String url = LinkManager.getResourceLink(resourceId); return LinkManager.getHref(url, o.toString()); } }); resourceNameField.setShowHover(true); resourceNameField.setHoverCustomizer(new HoverCustomizer() { public String hoverHTML(Object value, ListGridRecord listGridRecord, int rowNum, int colNum) { return AncestryUtil.getResourceHoverHTML(listGridRecord, 0); } }); fields.add(resourceNameField); ListGridField ancestryField = AncestryUtil.setupAncestryListGridField(); fields.add(ancestryField); nameField.setWidth("20%"); enabledField.setWidth(60); inComplianceField.setWidth(100); //driftHandlingModeField.setWidth("10%"); //intervalField.setWidth(100); baseDirField.setWidth("*"); attachedField.setWidth(70); templateField.setWidth("25%"); pinnedField.setWidth(70); changeSetField.setWidth(70); changeSetTimeField.setWidth(100); editField.setWidth(70); resourceNameField.setWidth("20%"); ancestryField.setWidth("40%"); } else { nameField.setWidth("20%"); changeSetField.setWidth(70); changeSetTimeField.setWidth(100); enabledField.setWidth(60); inComplianceField.setWidth(100); //driftHandlingModeField.setWidth("15%"); //intervalField.setWidth(70); baseDirField.setWidth("*"); attachedField.setWidth(70); templateField.setWidth("25%"); pinnedField.setWidth(70); editField.setWidth(70); } return fields; } @Override protected void executeFetch(final DSRequest request, final DSResponse response, final DriftDefinitionCriteria criteria) { this.driftService.findDriftDefinitionCompositesByCriteria(criteria, new AsyncCallback<PageList<DriftDefinitionComposite>>() { public void onFailure(Throwable caught) { CoreGUI.getErrorHandler().handleError(MSG.view_drift_failure_load(), caught); response.setStatus(RPCResponse.STATUS_FAILURE); processResponse(request.getRequestId(), response); } public void onSuccess(final PageList<DriftDefinitionComposite> result) { // if we don't have them grab the global perms to see later if we can link to to templates. if (null == globalPermissions) { new PermissionsLoader().loadExplicitGlobalPermissions(new PermissionsLoadedListener() { @Override public void onPermissionsLoaded(Set<Permission> permissions) { globalPermissions = (permissions != null) ? permissions : new HashSet<Permission>(); dataRetrieved(result, response, request); } }); } else { dataRetrieved(result, response, request); } } }); } /** * Additional processing to support entity-specific or cross-resource views, and something that can be overidden. */ protected void dataRetrieved(final PageList<DriftDefinitionComposite> result, final DSResponse response, final DSRequest request) { switch (entityContext.type) { // no need to disambiguate, the drift defs are for a single resource case Resource: response.setData(buildRecords(result)); setPagingInfo(response, result); processResponse(request.getRequestId(), response); break; case ResourceGroup: //TODO default: throw new IllegalArgumentException("Unsupported Context Type: " + entityContext); } } /** * Sub-classes can override this to add fine-grained control over the result set size. By default the * total rows are set to the total result set for the query, allowing proper paging. But some views (portlets) * may want to limit results to a small set (like most recent). * @param result * @param response * @param request * * @return should not exceed result.size(). */ protected int getTotalRows(final Collection<DriftDefinitionComposite> result, final DSResponse response, final DSRequest request) { return result.size(); } @Override protected DriftDefinitionCriteria getFetchCriteria(DSRequest request) { DriftDefinitionCriteria criteria = new DriftDefinitionCriteria(); switch (entityContext.getType()) { case Resource: criteria.addFilterResourceIds(entityContext.getResourceId()); break; case ResourceGroup: //TODO default: // no filter } criteria.fetchConfiguration(true); criteria.fetchTemplate(true); // filter out unsortable fields (i.e. fields sorted client-side only) PageControl pageControl = getPageControl(request); pageControl.removeOrderingField(ATTR_BASE_DIR_STRING); pageControl.removeOrderingField(ATTR_CHANGE_SET_CTIME); pageControl.removeOrderingField(ATTR_CHANGE_SET_VERSION); pageControl.removeOrderingField(ATTR_TEMPLATE); criteria.setPageControl(pageControl); return criteria; } @Override public DriftDefinitionComposite copyValues(Record from) { return null; } @Override public ListGridRecord copyValues(DriftDefinitionComposite from) { return convert(from); } public ListGridRecord convert(DriftDefinitionComposite from) { DriftDefinition def = from.getDriftDefinition(); DriftChangeSet<?> changeSet = from.getMostRecentChangeset(); ListGridRecord record = new ListGridRecord(); // We need this for Detect Now support record.setAttribute(ATTR_ENTITY, def); record.setAttribute(ATTR_ID, def.getId()); record.setAttribute(ATTR_NAME, def.getName()); record.setAttribute(ATTR_DRIFT_HANDLING_MODE, getDriftHandlingModeDisplayName(def.getDriftHandlingMode())); record.setAttribute(ATTR_INTERVAL, String.valueOf(def.getInterval())); record.setAttribute(ATTR_BASE_DIR_STRING, getBaseDirString(def.getBasedir())); record.setAttribute(ATTR_IS_ENABLED, String.valueOf(def.isEnabled())); record.setAttribute(ATTR_IS_ENABLED_ICON, ImageManager.getAvailabilityIcon(def.isEnabled())); record.setAttribute(ATTR_COMPLIANCE, def.getComplianceStatus().ordinal()); record.setAttribute(ATTR_COMPLIANCE_ICON, ImageManager.getAvailabilityIcon(def.getComplianceStatus() == DriftComplianceStatus.IN_COMPLIANCE)); // fixed value, just the edit icon record.setAttribute(ATTR_EDIT, hasWriteAccess ? ImageManager.getEditIcon() : ImageManager.getViewIcon()); record.setAttribute(ATTR_IS_PINNED, def.isPinned() ? ImageManager.getPinnedIcon() : ImageManager.getUnpinnedIcon()); record.setAttribute(ATTR_ATTACHED, def.isAttached() ? MSG.common_val_yes() : MSG.common_val_no()); if (def.getTemplate() != null) { record.setAttribute(ATTR_TEMPLATE, def.getTemplate().getName()); } else { record.setAttribute(ATTR_TEMPLATE, MSG.common_val_none()); } record.setAttribute(ATTR_CHANGE_SET_VERSION, (null != changeSet) ? String.valueOf(changeSet.getVersion()) : MSG.common_label_none()); record.setAttribute(ATTR_CHANGE_SET_CTIME, (null != changeSet) ? new Date(changeSet.getCtime()) : null); return record; } public static String getDriftHandlingModeDisplayName(DriftHandlingMode driftHandlingMode) { switch (driftHandlingMode) { case plannedChanges: return DRIFT_HANDLING_MODE_PLANNED; default: return DRIFT_HANDLING_MODE_NORMAL; } } private static String getBaseDirString(BaseDirectory basedir) { return basedir.getValueContext() + ":" + basedir.getValueName(); } protected EntityContext getEntityContext() { return entityContext; } protected void setEntityContext(EntityContext entityContext) { this.entityContext = entityContext; } }