blob: 8852231fdbe5cd4794f39be7e1781f58d40205ed [file] [log] [blame]
/*
-----------------------------------------------------------------------
-- CHESS M2M plugin --
-- --
-- Copyright (C) 2011-2012 --
-- University of Padova, ITALY --
-- --
-- Authors: -Alessandro Zovi azovi@math.unipd.it
-- -Intecs
-- --
-- All rights reserved. This program and the accompanying materials --
-- are made available under the terms of the Eclipse Public License --
-- v1.0 which accompanies this distribution, and is available at --
-- http://www.eclipse.org/legal/epl-v20.html --
-----------------------------------------------------------------------
*/
package org.polarsys.chess.m2m.handlers;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.Resource.Diagnostic;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.window.Window;
import org.eclipse.m2m.internal.qvt.oml.emf.util.ModelContent;
import org.eclipse.papyrus.MARTE.MARTE_AnalysisModel.GQAM.GaResourcesPlatform;
import org.eclipse.papyrus.MARTE.MARTE_AnalysisModel.SAM.SaAnalysisContext;
import org.eclipse.papyrus.editor.PapyrusMultiDiagramEditor;
import org.eclipse.papyrus.infra.core.services.ServiceException;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.InstanceSpecification;
import org.eclipse.uml2.uml.Model;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Stereotype;
import org.polarsys.chess.chessmlprofile.Core.CHGaResourcePlatform;
import org.polarsys.chess.chessmlprofile.Predictability.DeploymentConfiguration.HardwareBaseline.CH_HwProcessor;
import org.polarsys.chess.chessmlprofile.Predictability.RTComponentModel.CHRtPortSlot;
import org.polarsys.chess.chessmlprofile.util.Constants;
import org.polarsys.chess.core.util.AnalysisResultData;
import org.polarsys.chess.core.util.CHESSProjectSupport;
import org.polarsys.chess.core.util.HWAnalysisResultData;
import org.polarsys.chess.core.util.uml.ModelError;
import org.polarsys.chess.core.util.uml.ResourceUtils;
import org.polarsys.chess.core.util.uml.UMLUtils;
import org.polarsys.chess.core.views.ViewUtils;
import org.polarsys.chess.m2m.Activator;
import org.polarsys.chess.m2m.transformations.PIMPSMTransformationVERDE;
import org.polarsys.chess.m2m.transformations.TransUtil;
import org.polarsys.chess.m2m.transformations.TransformationResultsData;
import org.polarsys.chess.m2m.ui.AnalysisContextSelectionDialog;
import org.polarsys.chess.m2m.ui.SchedResultDialog;
import org.polarsys.chess.service.gui.utils.CHESSEditorUtils;
import org.polarsys.chess.validator.command.ChessGenericValidateCommand;
// TODO: Auto-generated Javadoc
/**
* The Class QVToUIHandlerVERDErealizes the handler for the scehdulability analysis command.
* @since 0.9
*/
public class QVToUIHandlerVERDE extends AbstractHandler {
/** The active shell. */
private Shell activeShell = null;
/** The in resource. */
private Resource inResource = null;
/** The context class. */
// private Class contextClass;
/** The sa analysis name. */
private String saAnalysisName;
/** The psm package name. */
private String psmPackageName;
/**
* Gets the active project.
*
* @param editor the editor
* @return the active project
*/
private IProject getActiveProject(IEditorPart editor) {
IFileEditorInput input = (IFileEditorInput) editor.getEditorInput();
IFile file = input.getFile();
return file.getProject();
}
/**
* Executes the schedulability analysis and shows the results.
* The analysis context to be analyzed is asked to the user through a dedicated dialog.
*
* @param event the event resulting from the invocation of the command
* @return null
* @throws ExecutionException the execution exception
* @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
* @see org.polarsys.chess.m2m.ui.AnalysisContextSelectionDialog
*/
public Object execute(final ExecutionEvent event) throws ExecutionException {
final IEditorPart editor = HandlerUtil.getActiveEditor(event);
if (!(CHESSEditorUtils.isCHESSProject(editor)))
return null;
try {
inResource = ResourceUtils.getUMLResource(((PapyrusMultiDiagramEditor) editor).getServicesRegistry());
} catch (ServiceException e) {
e.printStackTrace();
MessageDialog.openError(activeShell, "CHESS", "Unable to load the model");
}
IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event);
activeShell = window.getShell();
// run CHESS Validate Core Constraints to validate the model before running analysis
String label = "Validate model for CHESS Core Constraints";
final Model model = (Model) inResource.getContents().get(0);
ChessGenericValidateCommand chessValidateCommand = new ChessGenericValidateCommand(label,
org.polarsys.chess.validator.Activator.PLUGIN_ID, model);
boolean go = false;
if(chessValidateCommand != null) {
try {
chessValidateCommand.executeCommand(null, null);
}
catch (ExecutionException exception) {
return null;
}
if (chessValidateCommand.getMarkers()) {
org.eclipse.emf.common.util.Diagnostic diagnostic = chessValidateCommand.getDiagnostic();
List<org.eclipse.emf.common.util.Diagnostic> diagList = diagnostic.getChildren();
Boolean validationErrors = false;
for (org.eclipse.emf.common.util.Diagnostic theDiag : diagList) {
if (theDiag.getSource().equals(Constants.CHESS_VALIDATOR_PLUGIN) &&
theDiag.getSeverity()>org.eclipse.emf.common.util.Diagnostic.WARNING) {
validationErrors = true;
break;
}
}
if (validationErrors) {
go = MessageDialog.openQuestion(activeShell, "Validation Problems", "Errors found while validating the Model. Schedulability Analysis won't be performed correctly. Do you still want to continue?");
if (!go) {
return null;
}
}
}
}
else {
MessageDialog.openError(activeShell, "Schedulability Analysis", "Problems while perfoming model validation before analysis");
}
// end of model validation
//open a dialog to select the schedulability analysis context to be analyzed
//first get all the classes stereotyped as SaAnalysisContext
final List<Class> selection = new ArrayList<Class>();
EList<Element> elemList = model.allOwnedElements();
for (Element elem : elemList) {
//we're looking for a class stereotyped <<saAnalysisContext>> and NOT in PSM
if(elem instanceof Class && elem.getAppliedStereotype(TransUtil.SA_ANALYSIS_CTX) != null
&& !ViewUtils.isPSMView(ViewUtils.getView(elem))){
//as additional constraint, no workload is specified
SaAnalysisContext saAnalysisCtx = (SaAnalysisContext) elem.getStereotypeApplication
(elem.getAppliedStereotype(TransUtil.SA_ANALYSIS_CTX));
if(saAnalysisCtx.getWorkload().size() == 0){
selection.add((Class) elem);
}
}
}
if(selection.size() == 0){
MessageDialog.openWarning(activeShell, "CHESS", "no suitable analysis contexts in the model");
return null;
}
final List<CH_HwProcessor> chHwProcList = new ArrayList<CH_HwProcessor>();
//then open the dialog
String contextQN = null;
AnalysisContextSelectionDialog dialog = new AnalysisContextSelectionDialog(activeShell, selection, "Select Schedulability Context to analyze");
if (dialog.open() == Window.OK) {
}else{
return null;
}
contextQN = dialog.getContext();
if(contextQN == null || contextQN.isEmpty()){
return null;
}
Class contextClassTmp = null;
for (Element elem : model.allOwnedElements()) {
Stereotype saAnalysisContextStereo = elem.getAppliedStereotype(TransUtil.SA_ANALYSIS_CTX);
if(saAnalysisContextStereo != null &&
((NamedElement) elem).getQualifiedName().equals(contextQN)){
contextClassTmp = (Class) elem;
SaAnalysisContext saAnalysisContext = (SaAnalysisContext) elem.getStereotypeApplication(saAnalysisContextStereo);
List<CH_HwProcessor> tmpList = getPlatformChHwProcessors(saAnalysisContext, model);
chHwProcList.addAll(tmpList);
// Check that the Context Platform contains two CHGaResourcePlatform instances, one in ComponentView, one in DeploymentView
// and that at least on CH_HwPlatform is specified in the Context
if (chHwProcList.isEmpty() || !UMLUtils.checkPlatformsInContext(saAnalysisContext, model)) {
MessageDialog.openWarning(activeShell, "CHESS", "Context must specify a SW and a HW instance platform!");
return null;
}
try {
// Check that at least one Partition or Task is allocated on a Core of a ChHwProcessor specified in the Context
if(!UMLUtils.checkAllocationToCores(chHwProcList, model)) {
MessageDialog.openWarning(activeShell, "CHESS", "No partition or task allocated to Core!");
return null;
}
} catch (ModelError e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
final Class contextClass = contextClassTmp;
saAnalysisName = contextClass.getQualifiedName();
psmPackageName = contextClass.getName() +"_PSM";
final Job job = new Job("Transforming") {
protected IStatus run(IProgressMonitor monitor) {
try {
TransformationResultsData result =null;
try {
//CHESSProjectSupport.installMAST();
result = QVToUIHandlerVERDE.this.executeTimingAnalysis(editor, monitor);
//Reopen the editor
CHESSEditorUtils.reopenEditor(editor, false);
} catch (Exception e) {
throw e;
} finally {
getActiveProject(editor).refreshLocal(IResource.DEPTH_INFINITE, monitor);
}
//open sched analysis result
try {
//can active editor be different from just reopened CHESS ones? it should be not the case given that it has been just reopened
//inResource = ResourceUtils.getUMLResource(((CHESSEditor) editor).getServicesRegistry());
//Model model = (Model) inResource.getContents().get(0);
ModelContent inModel = TransUtil.loadModel(result.umlFile);
Model model = (Model) inModel.getContent().get(0);
openSchedAnalysisReport(model, result.res, chHwProcList, contextClass);
} catch (Exception e) {
e.printStackTrace();
throw new Exception("Unable to load the model and so open the schedAnalysisReport");
}
} catch (Exception e) {
e.printStackTrace();
return new Status(Status.ERROR, Activator.PLUGIN_ID, 1,
"Error in transformation "+ e.getMessage(), null);
}
if (monitor.isCanceled())
return Status.CANCEL_STATUS;
return Status.OK_STATUS;
}
};
job.addJobChangeListener(new JobChangeAdapter() {
public void done(IJobChangeEvent event) {
if (event.getResult().isOK())
CHESSProjectSupport.printlnToCHESSConsole("Job completed successfully");
else
CHESSProjectSupport.printlnToCHESSConsole("Job did not complete successfully");
}
});
job.setUser(true);
job.setPriority(Job.SHORT);
job.schedule();
return null;
}
/**
* Returns the list of CH_HwProcessors in this analysisContext.
*
* @param saAnalysisContext the sa analysis context
* @param model the model
* @return the platform ch hw processors
*/
public static List<CH_HwProcessor> getPlatformChHwProcessors(
SaAnalysisContext saAnalysisContext,
Model model) {
CH_HwProcessor chHwProcessor = null;
List<CH_HwProcessor> chHwProcessorList = new ArrayList<CH_HwProcessor>();
EList<GaResourcesPlatform> platformList = saAnalysisContext.getPlatform();
for (GaResourcesPlatform theGaResPlatform : platformList) {
if (theGaResPlatform instanceof CHGaResourcePlatform) {
CHGaResourcePlatform chGaResPlat = (CHGaResourcePlatform)theGaResPlatform;
org.eclipse.uml2.uml.Package thePackage = ViewUtils.getView(chGaResPlat.getBase_Package());
if (ViewUtils.getCHESSDeploymentPackage(model) == thePackage) {
EList<Element> allElems = (chGaResPlat.getBase_Package().allOwnedElements());
for (Element theElement : allElems) {
if (theElement instanceof InstanceSpecification) {
InstanceSpecification e = (InstanceSpecification) theElement;
if (e.getQualifiedName() != null
&& UMLUtils.isProcessorInstance(e)) {
chHwProcessor = UMLUtils.getStereotypeApplication(e, CH_HwProcessor.class);
chHwProcessorList.add(chHwProcessor);
}
}
}
}
}
}
return chHwProcessorList;
}
/**
* Collects all the needed information and invokes the PIMPSMTransformationVERDE.performTimingAnalysisWithMAST method
*
* @param editor the editor
* @param monitor the monitor
* @return the string resulting from the MAST execution (i.e. the system is/not schedulable) and the modified model
* @throws Exception the exception
* @see org.polarsys.chess.m2m.transformations.PIMPSMTransformationVERDE#performTimingAnalysisWithMAST(PapyrusMultiDiagramEditor, IFile, IProgressMonitor)
*/
public TransformationResultsData executeTimingAnalysis(IEditorPart editor, IProgressMonitor monitor) throws Exception {
monitor.beginTask("Transforming", 4);
IFile inputFile = CHESSProjectSupport.resourceToFile(inResource);
PIMPSMTransformationVERDE t = new PIMPSMTransformationVERDE();
Map<String, String> configProps = new HashMap<String, String>();
configProps.put("saAnalysis", saAnalysisName);
configProps.put("analysisType", "Schedulability");
t.setConfigProperty(configProps);
t.setPsmPackageName(psmPackageName);
final TransformationResultsData result = t.performTimingAnalysisWithMAST((PapyrusMultiDiagramEditor) editor, inputFile, monitor);
//CHESSProjectSupport.fileReplace(newFile, inputFile);
return result;
}
/**
* Open a simple, user-friendly report to display the analysis results.
*
* @param model the model
* @param result the result
* @param cpus the cpus
* @param saAnalysisContextClass the sa analysis context class
*/
public void openSchedAnalysisReport(Model model, final String result,
final List<CH_HwProcessor> cpus,
Class saAnalysisContextClass){
if (result == null)
return;
if (saAnalysisContextClass == null) {
return;
}
if(saAnalysisContextClass.eIsProxy()){
saAnalysisContextClass = (Class) EcoreUtil.resolve(saAnalysisContextClass, model);
}
final List<HWAnalysisResultData> hwResults = UMLUtils.getHWAnalysisResults(saAnalysisContextClass);
final List<AnalysisResultData> analysisResData = UMLUtils.getAnalysisResults(saAnalysisContextClass);
//and open a simple, user-friendly report
// final List<CHRtPortSlot> specifications = new ArrayList<CHRtPortSlot>();
// for (Element elem : model.allOwnedElements()) {
// CHRtPortSlot chrtSlot = UMLUtils.getStereotypeApplication(elem, CHRtPortSlot.class);
// //if(chrtSlot != null && UMLUtils.getStereotypeApplication(chrtSlot.getBase_Slot().getOwner(), IdentifInstance.class) != null){
// if(chrtSlot != null){
// specifications.add(chrtSlot);
// }
// };
final Display display = PlatformUI.getWorkbench().getDisplay();
display.asyncExec(new Runnable() {
@Override
public void run() {
Shell shell = new Shell(display);
//SchedResultDialog dialog = new SchedResultDialog(shell, result, specifications, cpus, hwResults);
SchedResultDialog dialog = new SchedResultDialog(shell, result, analysisResData, hwResults);
if (dialog.open() == Window.OK) {
System.out.println("OK");
}
}
});
}
// @SuppressWarnings("unused")
// private ModelSet getEditorResourceSet(IEditorPart editor)
// throws Exception {
// ModelSet resourceSet = null;
// try {
// resourceSet = (ModelSet)((ServicesRegistry)editor.getAdapter(ServicesRegistry.class)).getService(ModelSet.class);
// } catch (ServiceException e) {
// e.printStackTrace();
// throw new Exception("Unable to get the service registry");
// }
// return resourceSet;
// }
}