/* * RHQ Management Platform * Copyright (C) 2005-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, 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.report.measurement; import java.util.ArrayList; import java.util.Collection; import java.util.Date; 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.data.DSRequest; import com.smartgwt.client.data.DSResponse; import com.smartgwt.client.data.DataSourceField; import com.smartgwt.client.data.Record; import com.smartgwt.client.widgets.HTMLFlow; 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 org.rhq.core.domain.criteria.Criteria; import org.rhq.core.domain.measurement.composite.MeasurementOOBComposite; import org.rhq.core.domain.resource.ResourceType; 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.LinkManager; import org.rhq.coregui.client.components.table.TimestampCellFormatter; 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; import org.rhq.coregui.client.util.MeasurementConverterClient; import org.rhq.coregui.client.util.RPCDataSource; /** * @author Greg Hinkle */ public class MeasurementOOBDataSource extends RPCDataSource<MeasurementOOBComposite, Criteria> { private int maximumFactor = 0; public MeasurementOOBDataSource() { List<DataSourceField> fields = addDataSourceFields(); addFields(fields); } /** * 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() { ArrayList<ListGridField> fields = new ArrayList<ListGridField>(); 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) { String url = LinkManager.getResourceLink(listGridRecord.getAttributeAsInt(AncestryUtil.RESOURCE_ID)); 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(); ancestryField.setCanSortClientOnly(true); fields.add(ancestryField); ListGridField scheduleNameField = new ListGridField("scheduleName", MSG .dataSource_measurementOob_field_scheduleName()); fields.add(scheduleNameField); ListGridField timestampField = new ListGridField("timestamp", MSG.common_title_timestamp()); timestampField.setCellFormatter(new TimestampCellFormatter(TimestampCellFormatter.DATE_TIME_FORMAT_SHORT)); timestampField.setShowHover(true); timestampField.setHoverCustomizer(TimestampCellFormatter.getHoverCustomizer("timestamp")); fields.add(timestampField); ListGridField bandField = new ListGridField("formattedBaseband", MSG .dataSource_measurementOob_field_formattedBaseband()); bandField.setCanSortClientOnly(true); fields.add(bandField); ListGridField outlierField = new ListGridField("formattedOutlier", MSG .dataSource_measurementOob_field_formattedOutlier()); outlierField.setCanSortClientOnly(true); fields.add(outlierField); ListGridField factorField = new ListGridField("factor", MSG.dataSource_measurementOob_field_factor()); fields.add(factorField); resourceNameField.setWidth("20%"); ancestryField.setWidth("25%"); timestampField.setWidth(100); scheduleNameField.setWidth("20%"); bandField.setWidth("10%"); outlierField.setWidth("10%"); factorField.setWidth("10%"); return fields; } @Override protected void executeFetch(final DSRequest request, final DSResponse response, final Criteria unused) { PageControl pc = getPageControl(request); GWTServiceLookup.getMeasurementDataService().getSchedulesWithOOBs(null, null, null, pc, new AsyncCallback<PageList<MeasurementOOBComposite>>() { public void onFailure(Throwable caught) { CoreGUI.getErrorHandler().handleError(MSG.dataSource_measurementOob_error_fetchFailure(), caught); } public void onSuccess(final PageList<MeasurementOOBComposite> result) { Set<Integer> typesSet = new HashSet<Integer>(); Set<String> ancestries = new HashSet<String>(); for (MeasurementOOBComposite composite : result) { typesSet.add(composite.getResourceTypeId()); ancestries.add(composite.getResourceAncestry()); } // 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); Record[] records = buildRecords(result); for (Record record : records) { // To avoid a lot of unnecessary String construction, be lazy about building ancestry hover text. // Store the types map off the records so we can build a detailed hover string as needed. record.setAttribute(AncestryUtil.RESOURCE_ANCESTRY_TYPES, typesWrapper); // Build the decoded ancestry Strings now for display record.setAttribute(AncestryUtil.RESOURCE_ANCESTRY_VALUE, AncestryUtil .getAncestryValue(record)); } response.setData(records); // for paging to work we have to specify size of full result set response.setTotalRows(result.getTotalSize()); processResponse(request.getRequestId(), response); } }); } }); } @Override protected Criteria getFetchCriteria(DSRequest request) { // we don't use criterias for this datasource, just return null return null; } protected String getSortFieldForColumn(String columnName) { // Allow server-side sorting for only unmodified queries, these keywords are for MeasurementOOBManagerBean. // Rest of the fields should have client-side sorting only. String sortField = null; if("scheduleName".equals(columnName)) { sortField = "def.displayName"; } else if("resourceName".equals(columnName)) { sortField = "res.name"; } else if("timestamp".equals(columnName)) { sortField = "o.timestamp"; } else if("factor".equals(columnName)) { sortField = "o.oobFactor"; } return sortField; } @Override public MeasurementOOBComposite copyValues(Record from) { throw new UnsupportedOperationException("OOBs Read only"); } @Override public ListGridRecord[] buildRecords(Collection<MeasurementOOBComposite> dataObjects) { for (MeasurementOOBComposite oob : dataObjects) { if (oob.getFactor() > maximumFactor) { maximumFactor = oob.getFactor(); } } return super.buildRecords(dataObjects); } @Override public ListGridRecord copyValues(MeasurementOOBComposite from) { applyFormatting(from); ListGridRecord record = new ListGridRecord(); record.setAttribute("scheduleId", from.getScheduleId()); record.setAttribute("scheduleName", from.getScheduleName()); record.setAttribute("definitionId", from.getDefinitionId()); record.setAttribute("timestamp", new Date(from.getTimestamp())); record.setAttribute("factor", from.getFactor()); record.setAttribute("formattedBaseband", from.getFormattedBaseband()); record.setAttribute("formattedOutlier", from.getFormattedOutlier()); record.setAttribute("blMin", from.getBlMin()); record.setAttribute("blMax", from.getBlMax()); record.setAttribute("parentId", from.getParentId()); record.setAttribute("parentName", from.getParentName()); // for ancestry handling record.setAttribute(AncestryUtil.RESOURCE_ID, from.getResourceId()); record.setAttribute(AncestryUtil.RESOURCE_NAME, from.getResourceName()); record.setAttribute(AncestryUtil.RESOURCE_ANCESTRY, from.getResourceAncestry()); record.setAttribute(AncestryUtil.RESOURCE_TYPE_ID, from.getResourceTypeId()); int factorRankingWidth = (int) (((double) from.getFactor()) / (double) maximumFactor * 100d); record.setBackgroundComponent(new HTMLFlow("<div style=\"width: " + factorRankingWidth + "%; height: 100%; background-color: #A5B391;\"> </div>")); return record; } private void applyFormatting(MeasurementOOBComposite oob) { oob.setFormattedOutlier(MeasurementConverterClient.format(oob.getOutlier(), oob.getUnits(), true)); formatBaseband(oob); } private void formatBaseband(MeasurementOOBComposite oob) { String min = MeasurementConverterClient.format(oob.getBlMin(), oob.getUnits(), true); String max = MeasurementConverterClient.format(oob.getBlMax(), oob.getUnits(), true); oob.setFormattedBaseband(min + ", " + max); } }