LatencyExcelReport.java
/**
* Copyright (c) 2004-2025 Carnegie Mellon University and others. (see Contributors file).
* All Rights Reserved.
*
* NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
* KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
* OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
* MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
*
* This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
* SPDX-License-Identifier: EPL-2.0
*
* Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
*
* This program includes and/or can make use of certain third party source code, object code, documentation and other
* files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
* configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
* conditions contained in any such Third Party Software or separate license file distributed with such Third Party
* Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party benefici-
* aries to this license with respect to the terms applicable to their Third Party Software. Third Party Software li-
* censes only apply to the Third Party Software and not any other portion of this program or this program as a whole.
*/
package org.osate.analysis.flows.model;
import java.io.IOException;
import java.util.Locale;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.URI;
import org.eclipse.ui.statushandlers.StatusManager;
import org.osate.aadl2.instance.InstanceObject;
import org.osate.aadl2.modelsupport.resources.OsateResourceUtil;
import org.osate.aadl2.modelsupport.util.AadlUtil;
import org.osate.analysis.flows.FlowanalysisPlugin;
import org.osate.analysis.flows.internal.utils.FlowLatencyUtil;
import org.osate.result.AnalysisResult;
import org.osate.result.Diagnostic;
import org.osate.result.Result;
import org.osate.result.util.ResultUtil;
import jxl.Workbook;
import jxl.WorkbookSettings;
import jxl.format.CellFormat;
import jxl.format.Colour;
import jxl.format.UnderlineStyle;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
public class LatencyExcelReport {
private static final WritableCellFormat BOLD_FORMAT = new WritableCellFormat(
new WritableFont(WritableFont.ARIAL, 10, WritableFont.BOLD));
private static final WritableCellFormat ERROR_FORMAT;
private static final WritableCellFormat WARNING_FORMAT;
static {
WritableFont boldWhiteFont = new WritableFont(WritableFont.ARIAL, 10, WritableFont.BOLD, false,
UnderlineStyle.NO_UNDERLINE, Colour.WHITE);
ERROR_FORMAT = new WritableCellFormat(boldWhiteFont);
WARNING_FORMAT = new WritableCellFormat(boldWhiteFont);
try {
ERROR_FORMAT.setBackground(Colour.RED);
WARNING_FORMAT.setBackground(Colour.LIGHT_ORANGE);
} catch (WriteException e) {
String pluginId = FlowanalysisPlugin.getDefault().getBundle().getSymbolicName();
IStatus status = new Status(IStatus.ERROR, pluginId, e.getMessage(), e);
StatusManager.getManager().handle(status);
}
}
public static void generateExcelReport(AnalysisResult latres) {
IFile file = getExcelFile(latres);
try {
if (file.exists()) {
file.delete(true, null);
}
if (!latres.getResults().isEmpty()) {
AadlUtil.makeSureFoldersExist(file.getFullPath());
String reportHeader = "Latency analysis with preference settings: "
+ FlowLatencyUtil.getParametersAsDescriptions(latres);
WorkbookSettings wbSettings = new WorkbookSettings();
wbSettings.setLocale(new Locale("en", "EN"));
wbSettings.setCellValidationDisabled(false);
wbSettings.setRationalization(false);
WritableWorkbook workbook = Workbook.createWorkbook(file.getLocation().toFile(), wbSettings);
int sheetNumber = 0, i = 1;
for (Result result : latres.getResults()) {
InstanceObject instanceObject = (InstanceObject) result.getModelElement();
String flowName = instanceObject.getComponentInstancePath();
String systemName = instanceObject.getSystemInstance().getComponentClassifier().getName();
String inMode = ResultUtil.getString(result, 0);
String sheetName;
if (inMode.isEmpty()) {
sheetName = flowName;
} else {
sheetName = flowName + " in mode " + inMode;
}
// Excel has a length limitation of 31 characters for worksheet name
// adjust the name to keep worksheet name unique
if (sheetName != null && sheetName.length() > 31) {
String s = String.valueOf(i++);
sheetName = sheetName.substring(0, 31 - s.length()) + s;
}
WritableSheet sheet = workbook.createSheet(sheetName, sheetNumber);
sheet.addCell(new Label(0, 0, reportHeader, BOLD_FORMAT));
sheet.addCell(new Label(0, 2, "Latency results for end-to-end flow '" + flowName + "' of system '"
+ systemName + "'" + inMode, BOLD_FORMAT));
sheet.addCell(new Label(0, 4, "Result", BOLD_FORMAT));
sheet.addCell(new Label(1, 4, "Min Specified", BOLD_FORMAT));
sheet.addCell(new Label(2, 4, "Min Actual", BOLD_FORMAT));
sheet.addCell(new Label(3, 4, "Min Method", BOLD_FORMAT));
sheet.addCell(new Label(4, 4, "Max Specified", BOLD_FORMAT));
sheet.addCell(new Label(5, 4, "Max Actual", BOLD_FORMAT));
sheet.addCell(new Label(6, 4, "Max Method", BOLD_FORMAT));
sheet.addCell(new Label(7, 4, "Comments", BOLD_FORMAT));
int row = 5;
for (Result contributor : result.getSubResults()) {
for (Result subc : contributor.getSubResults()) {
addContributor(sheet, row, subc, true);
row++;
}
addContributor(sheet, row, contributor, false);
row++;
}
sheet.addCell(new Label(0, row, "Latency Total"));
sheet.addCell(new Label(1, row, ResultUtil.getReal(result, 3) + "ms"));
sheet.addCell(new Label(2, row, ResultUtil.getReal(result, 1) + "ms"));
sheet.addCell(new Label(4, row, ResultUtil.getReal(result, 4) + "ms"));
sheet.addCell(new Label(5, row, ResultUtil.getReal(result, 2) + "ms"));
row++;
sheet.addCell(new Label(0, row, "Specified End To End Latency"));
sheet.addCell(new Label(2, row, ResultUtil.getReal(result, 5) + "ms"));
sheet.addCell(new Label(5, row, ResultUtil.getReal(result, 6) + "ms"));
row++;
sheet.addCell(new Label(0, row, "End To End Latency Summary", BOLD_FORMAT));
row++;
for (Diagnostic dia : result.getDiagnostics()) {
sheet.addCell(new Label(0, row, dia.getDiagnosticType().toString(), getCellFormat(dia)));
sheet.addCell(new Label(1, row, dia.getMessage()));
row++;
}
sheetNumber++;
}
workbook.write();
workbook.close();
file.refreshLocal(IResource.DEPTH_INFINITE, null);
}
} catch (CoreException e) {
StatusManager.getManager().handle(e, FlowanalysisPlugin.getDefault().getBundle().getSymbolicName());
} catch (IOException | WriteException e) {
String pluginId = FlowanalysisPlugin.getDefault().getBundle().getSymbolicName();
IStatus status = new Status(IStatus.ERROR, pluginId, e.getMessage(), e);
StatusManager.getManager().handle(status);
}
}
private static void addContributor(WritableSheet sheet, int row, Result contributor, boolean subcontributor)
throws WriteException {
String comp = FlowLatencyUtil.getContributorType(contributor.getModelElement()) + " "
+ FlowLatencyUtil.getFullComponentContributorName(contributor.getModelElement());
String flowSpecName = ResultUtil.getString(contributor, 6);
if (!flowSpecName.isEmpty()) {
comp = comp + " (" + flowSpecName + ")";
}
if (subcontributor) {
comp = "(" + comp + ")";
}
sheet.addCell(new Label(0, row, comp));
sheet.addCell(new Label(1, row, ResultUtil.getReal(contributor, 2) + "ms"));
sheet.addCell(new Label(2, row, ResultUtil.getReal(contributor, 0) + "ms"));
sheet.addCell(new Label(3, row, ResultUtil.getString(contributor, 4)));
sheet.addCell(new Label(4, row, ResultUtil.getReal(contributor, 3) + "ms"));
sheet.addCell(new Label(5, row, ResultUtil.getReal(contributor, 1) + "ms"));
sheet.addCell(new Label(6, row, ResultUtil.getString(contributor, 5)));
int column = 7;
for (Diagnostic dia : contributor.getDiagnostics()) {
sheet.addCell(new Label(column, row, dia.getMessage()));
column++;
}
}
private static CellFormat getCellFormat(Diagnostic dia) {
switch (dia.getDiagnosticType()) {
case ERROR:
return ERROR_FORMAT;
case WARNING:
return WARNING_FORMAT;
default:
return BOLD_FORMAT;
}
}
private static IFile getExcelFile(AnalysisResult ar) {
URI arURI = ar.eResource().getURI();
URI excelURI = arURI.trimFileExtension().appendFileExtension("xls");
return OsateResourceUtil.toIFile(excelURI);
}
}