| /* |
| ----------------------------------------------------------------------- |
| -- Copyright (C) 2011-2016 -- |
| -- University of Firenze, Italy -- |
| -- Intecs S.p.A., Italy -- |
| -- -- |
| -- 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 -- |
| -- -- |
| -- Contributors: -- |
| -- Leonardo Montecchi lmontecchi@unifi.it -- |
| -- Nicholas Pacini nicholas.pacini@intecs.it -- |
| ----------------------------------------------------------------------- |
| */ |
| |
| package org.polarsys.chess.statebased; |
| |
| import java.io.BufferedReader; |
| import java.io.ByteArrayInputStream; |
| import java.io.DataInputStream; |
| import java.io.FileInputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| import java.lang.reflect.InvocationTargetException; |
| import java.net.MalformedURLException; |
| import java.net.SocketTimeoutException; |
| import java.net.URL; |
| import java.net.UnknownHostException; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.Map; |
| |
| import org.polarsys.chess.chessmlprofile.chessmlprofilePackage; |
| import org.polarsys.chess.chessmlprofile.Core.CHESS; |
| import org.polarsys.chess.core.util.CHESSProjectSupport; |
| import org.polarsys.chess.core.util.uml.ResourceUtils; |
| import org.polarsys.chess.service.gui.utils.CHESSEditorUtils; |
| import org.polarsys.chess.statebased.daemon.ParameterList; |
| 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.IFolder; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.MultiStatus; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.ecore.EPackage; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.ecore.xmi.impl.EcoreResourceFactoryImpl; |
| import org.eclipse.emf.transaction.RecordingCommand; |
| import org.eclipse.emf.transaction.TransactionalEditingDomain; |
| import org.eclipse.jface.dialogs.ErrorDialog; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.dialogs.ProgressMonitorDialog; |
| import org.eclipse.jface.operation.IRunnableWithProgress; |
| import org.eclipse.m2m.atl.core.ATLCoreException; |
| import org.eclipse.m2m.atl.core.IExtractor; |
| import org.eclipse.m2m.atl.core.IInjector; |
| import org.eclipse.m2m.atl.core.IModel; |
| import org.eclipse.m2m.atl.core.IReferenceModel; |
| import org.eclipse.m2m.atl.core.ModelFactory; |
| import org.eclipse.m2m.atl.core.emf.EMFExtractor; |
| import org.eclipse.m2m.atl.core.emf.EMFInjector; |
| import org.eclipse.m2m.atl.core.emf.EMFModelFactory; |
| import org.eclipse.m2m.atl.core.launch.ILauncher; |
| import org.eclipse.m2m.atl.core.service.CoreService; |
| import org.eclipse.m2m.atl.engine.emfvm.launch.EMFVMLauncher; |
| import org.eclipse.papyrus.editor.PapyrusMultiDiagramEditor; |
| import org.eclipse.papyrus.infra.core.services.ServiceException; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.ui.IFileEditorInput; |
| import org.eclipse.uml2.uml.Component; |
| import org.eclipse.uml2.uml.Element; |
| import org.eclipse.uml2.uml.Model; |
| import org.eclipse.uml2.uml.Package; |
| import org.eclipse.uml2.uml.PackageableElement; |
| import org.eclipse.uml2.uml.Stereotype; |
| |
| public class StateBasedTransformationCommand extends AbstractHandler { |
| |
| // private static final String RESURCEPLATFORM = "CHESS::Core::CHGaResourcePlatform"; |
| |
| private static final String PLUGIN_PATH = "platform:/plugin/org.polarsys.chess.statebased"; |
| |
| private static final String sysmlPath = "http://www.eclipse.org/papyrus/0.7.0/SysML"; |
| private static final String martePath = "http://www.eclipse.org/papyrus/MARTE/1"; |
| // private static final String chessPath = "http://schemas/CHESS/_PfAJsMe6Ed-7etIj5eTw0Q/19"; |
| private static final String chessPath = "ttp://CHESS"; |
| private static final String umlPath = "http://www.eclipse.org/uml2/4.0.0/UML"; |
| private static final String imPath = PLUGIN_PATH + "/metamodels/IM2.ecore"; |
| private static final String pnmlPath = PLUGIN_PATH + "/metamodels/placeTransition.ecore"; |
| |
| private static final String STEP1_PATH = PLUGIN_PATH + "/transformations/CHESS2IM.asm"; |
| private static final String STEP2_PATH = PLUGIN_PATH + "/transformations/IDM2PNML.asm"; |
| private static final String STEP3_PATH = PLUGIN_PATH + "/transformations/PNML2DEEM.asm"; |
| |
| public static final String COMMAND_ID = "org.chess.stateBasedTransformationCommandID"; |
| |
| private static final String SBANALYSIS_DIR = "StateBasedAnalysis"; |
| private static final String UML = ".uml"; |
| private static final String IM = ".idm"; |
| private static final String PNML = ".pnml"; |
| private static final String DEEM = ".deem"; |
| |
| private static IInjector injector; |
| private static IExtractor extractor; |
| |
| private static IReferenceModel sysmlMetamodel; |
| private static IReferenceModel marteMetamodel; |
| private static IReferenceModel chessMetamodel; |
| private static IReferenceModel umlMetamodel; |
| private static IReferenceModel imMetamodel; |
| private static IReferenceModel pnmlMetamodel; |
| |
| |
| private static String chessModelPath; |
| private static String imModelPath; |
| private static String pnmlModelPath; |
| private static String resultName; |
| |
| private static final String NETNAME = "NET_NAME"; |
| private static final String MEASURE = " ->"; |
| private static final String CHESS_QN = "CHESS::Core::CHESS"; |
| private static final String STATEBASED_ANALYSIS_QN = "CHESS::Dependability::StateBased::StateBasedAnalysis::StateBasedAnalysis"; |
| private static final String RESULT = "measureEvaluationResult"; |
| |
| private static Shell shell = new Shell(); |
| private static final String ERROR_MSG = "Problems while perfoming State-Based Analysis: "; |
| |
| |
| @Override |
| public Object execute(ExecutionEvent event) throws ExecutionException { |
| |
| final PapyrusMultiDiagramEditor editor = CHESSEditorUtils.getCHESSEditor(); |
| final ParameterList params = DEEMClient.getParameters(); |
| try{ |
| |
| ProgressMonitorDialog pmDialog = new ProgressMonitorDialog(shell); |
| pmDialog.run(true, true, new IRunnableWithProgress(){ |
| @Override |
| public void run(IProgressMonitor monitor) /*throws InterruptedException*/ { |
| //int largeStep = params.getMaximumBatches(); |
| int smallStep = params.getMinimumBatches(); |
| int numSubTasks = 3*smallStep/10 + smallStep; |
| |
| monitor.beginTask("Running State-Based Analysis...", numSubTasks); |
| if (monitor.isCanceled()) |
| return; |
| monitor.subTask("Rebuilding instances..."); |
| //TODO: CallBuildInstances(editor); //skipped at the moment |
| monitor.worked(smallStep/10); |
| |
| monitor.subTask("Performing model transformations..."); |
| IFile tr = RunTransformations(editor, monitor); |
| monitor.worked(smallStep/10); |
| |
| monitor.subTask("Connecting to DEEM server..."); |
| String res = connectToDeem(tr, monitor); |
| |
| if(res != null && !res.isEmpty()){ |
| monitor.subTask("Propagating analysis results to the model..."); |
| backPropagation(res, editor); |
| monitor.worked(smallStep/10); |
| }else{ |
| System.out.println("Error: Unable to retrieve results from DEEM server."); |
| } |
| |
| //Thread.sleep(2000); |
| |
| monitor.worked(1); |
| monitor.done(); |
| } |
| }); |
| } catch (InvocationTargetException e) { |
| e.printStackTrace(); |
| CHESSProjectSupport.printlnToCHESSConsole(e.toString()); |
| displayMessage(shell, ERROR_MSG + e.toString(), MessageDialog.ERROR); |
| |
| } catch (InterruptedException e) { |
| e.printStackTrace(); |
| CHESSProjectSupport.printlnToCHESSConsole(e.toString()); |
| displayMessage(shell, ERROR_MSG + e.toString(), MessageDialog.ERROR); |
| } |
| |
| return null; |
| } |
| |
| |
| private static IFile RunTransformations(PapyrusMultiDiagramEditor editor, IProgressMonitor monitor ){ |
| |
| try { |
| |
| IFileEditorInput input = (IFileEditorInput) editor.getEditorInput(); |
| IFile file = input.getFile(); |
| IProject project = file.getProject(); |
| |
| IFolder folder = project.getFolder(SBANALYSIS_DIR); |
| CHESSProjectSupport.createFolder(folder); |
| |
| Resource inResource = ResourceUtils.getUMLResource(editor.getServicesRegistry()); |
| IFile inputFile = CHESSProjectSupport.resourceToFile(inResource); |
| IFile inputCopy = CHESSProjectSupport.copyFile(inputFile, SBANALYSIS_DIR, inputFile.getName()); |
| |
| chessModelPath = inputCopy.getFullPath().toString(); |
| |
| CoreService.registerLauncher("EMF-specific VM", EMFVMLauncher.class); |
| CoreService.registerFactory("EMF", EMFModelFactory.class); |
| CoreService.registerExtractor("EMF", EMFExtractor.class); |
| CoreService.registerInjector("EMF", EMFInjector.class); |
| |
| injector = CoreService.getInjector("EMF"); |
| extractor = CoreService.getExtractor("EMF"); |
| |
| ModelFactory factory = CoreService.getModelFactory("EMF"); |
| |
| //IReferenceModel(s) for the meta-models |
| sysmlMetamodel = factory.newReferenceModel(); |
| marteMetamodel = factory.newReferenceModel(); |
| chessMetamodel = factory.newReferenceModel(); |
| umlMetamodel = factory.newReferenceModel(); |
| imMetamodel = factory.newReferenceModel(); |
| |
| //Register EPackages |
| EPackage.Registry.INSTANCE.put(sysmlPath, org.eclipse.papyrus.sysml.SysmlPackage.eINSTANCE); |
| EPackage.Registry.INSTANCE.put(martePath, org.eclipse.papyrus.MARTE.MARTEPackage.eINSTANCE); |
| EPackage.Registry.INSTANCE.put(chessPath, chessmlprofilePackage.eINSTANCE); |
| EPackage.Registry.INSTANCE.put(umlPath, org.eclipse.uml2.uml.UMLPackage.eINSTANCE); |
| Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("ecore", new EcoreResourceFactoryImpl()); |
| |
| /** |
| * run CHESS -> IM transformation: |
| * module CHESS2IM; |
| * create OUT: IM from IN1: CHESS, IN2: UML2, IN3: MARTE; |
| */ |
| |
| //Load meta-models |
| injector.inject(sysmlMetamodel, sysmlPath); |
| injector.inject(marteMetamodel, martePath); |
| injector.inject(chessMetamodel, chessPath); |
| injector.inject(umlMetamodel, umlPath); |
| injector.inject(imMetamodel, imPath); |
| |
| // Create models |
| IModel sysmlModel = factory.newModel(sysmlMetamodel); |
| IModel marteModel = factory.newModel(marteMetamodel); |
| IModel chessModel = factory.newModel(chessMetamodel); |
| IModel umlModel = factory.newModel(umlMetamodel); |
| IModel imModel = factory.newModel(imMetamodel); |
| |
| // Load the chess model |
| injector.inject(sysmlModel, chessModelPath); |
| injector.inject(marteModel, chessModelPath); |
| injector.inject(chessModel, chessModelPath); |
| injector.inject(umlModel, chessModelPath); |
| |
| //Initialize launcher |
| ILauncher launcher = null; |
| launcher = (EMFVMLauncher)CoreService.getLauncher("EMF-specific VM"); |
| launcher.initialize(Collections.<String, Object> emptyMap()); |
| |
| //Add models to launch transformation |
| launcher.addInModel(chessModel, "IN1", "CHESS"); |
| launcher.addInModel(chessModel, "IN2", "UML"); |
| launcher.addInModel(marteModel, "IN3", "MARTE"); |
| launcher.addInModel(sysmlModel, "IN4", "SYSML"); |
| launcher.addOutModel(imModel, "OUT", "IM"); |
| |
| //Create a module of the CHESS2IM transformation |
| URL asmTransformation = new URL(STEP1_PATH); |
| Object loadedModule = launcher.loadModule(asmTransformation.openStream()); |
| |
| //Launch |
| launcher.launch(ILauncher.RUN_MODE, new NullProgressMonitor(), Collections |
| .<String, Object> emptyMap(), loadedModule); |
| |
| //Save model |
| imModelPath = changeSuffix(chessModelPath, UML, IM); |
| extractor.extract(imModel, imModelPath); |
| |
| System.out.println("CHESS -> IM ... DONE!"); |
| monitor.worked(1); |
| |
| /** |
| * run IM -> PNML transformation: |
| * module IDM2PNML; |
| * create OUT : PNML from IN : IDM; |
| */ |
| |
| //IReferenceModel for PNML Metamodel |
| pnmlMetamodel = factory.newReferenceModel(); |
| |
| //inject PNML Metamodel |
| injector.inject(pnmlMetamodel, pnmlPath); |
| |
| //create IModels from PNML Metamodel |
| IModel pnmlModel = factory.newModel(pnmlMetamodel); |
| |
| // reset the launcher |
| launcher = null; |
| launcher = (EMFVMLauncher)CoreService.getLauncher("EMF-specific VM"); |
| launcher.initialize(Collections.<String, Object> emptyMap()); |
| |
| //Add in and out Models to the launcher |
| launcher.addInModel(imModel, "IN", "IDM"); |
| launcher.addOutModel(pnmlModel, "OUT", "PNML"); |
| //launcher.addOutModel(measuresModel, "out2", "MOI"); |
| |
| //create a module of the IDM2PNML.asm transformation |
| asmTransformation = new URL(STEP2_PATH); |
| loadedModule = launcher.loadModule(asmTransformation.openStream()); |
| |
| //launch transformation |
| launcher.launch(ILauncher.RUN_MODE, new NullProgressMonitor(), Collections |
| .<String, Object> emptyMap(), loadedModule); |
| |
| //save pnml model |
| pnmlModelPath = changeSuffix(chessModelPath, UML, PNML); |
| extractor.extract(pnmlModel, pnmlModelPath); |
| |
| System.out.println("IM -> PNML ... DONE!"); |
| monitor.worked(1); |
| |
| /** |
| * run PNML -> DEEM transformation: |
| * module PNML2DEEM; |
| */ |
| |
| // reset the launcher |
| launcher = null; |
| launcher = (EMFVMLauncher)CoreService.getLauncher("EMF-specific VM"); |
| launcher.initialize(Collections.<String, Object> emptyMap()); |
| |
| //Add in Model to the launcher |
| launcher.addInModel(pnmlModel, "IN", "PNML"); |
| //launcher.addOutModel(deemModel, "out1", "DEEM"); |
| |
| //create a module of the PNML2DEEM.asm transformation |
| asmTransformation = new URL(STEP3_PATH); |
| loadedModule = launcher.loadModule(asmTransformation.openStream()); |
| |
| //launch transformation |
| Object result = launcher.launch(ILauncher.RUN_MODE, new NullProgressMonitor(), Collections |
| .<String, Object> emptyMap(), loadedModule); |
| |
| //Save (write to file) the result |
| resultName = changeSuffix(inputFile.getName(), UML, DEEM); |
| |
| String stResult = result.toString(); |
| stResult = stResult.substring(1, stResult.lastIndexOf(']')); |
| InputStream is = new ByteArrayInputStream(stResult.getBytes("UTF-8")); |
| |
| IFile resultFile = folder.getFile(resultName); |
| //if (!resultFile.exists()){ //overwrite previous results (otherwise they are not updated when the model changes) |
| resultFile.delete(true, null); |
| resultFile.create(is, IResource.FORCE, null); |
| //} |
| |
| System.out.println("PNML -> DEEM ... DONE!"); |
| monitor.worked(1); |
| return resultFile; |
| |
| //exception handling? |
| } catch (ServiceException e) { |
| e.printStackTrace(); |
| CHESSProjectSupport.printlnToCHESSConsole(e.toString()); |
| displayMessage(shell, ERROR_MSG + e.toString(), MessageDialog.ERROR); |
| return null; |
| } catch (ATLCoreException e) { |
| e.printStackTrace(); |
| CHESSProjectSupport.printlnToCHESSConsole(e.toString()); |
| displayMessage(shell, ERROR_MSG + e.toString(), MessageDialog.ERROR); |
| return null; |
| } catch (MalformedURLException e) { |
| e.printStackTrace(); |
| CHESSProjectSupport.printlnToCHESSConsole(e.toString()); |
| displayMessage(shell, ERROR_MSG + e.toString(), MessageDialog.ERROR); |
| return null; |
| } catch (IOException e) { |
| e.printStackTrace(); |
| CHESSProjectSupport.printlnToCHESSConsole(e.toString()); |
| displayMessage(shell, ERROR_MSG + e.toString(), MessageDialog.ERROR); |
| return null; |
| } catch (CoreException e) { |
| e.printStackTrace(); |
| CHESSProjectSupport.printlnToCHESSConsole(e.toString()); |
| displayMessage(shell, ERROR_MSG + e.toString(), MessageDialog.ERROR); |
| return null; |
| } catch (Exception e) { |
| e.printStackTrace(); |
| CHESSProjectSupport.printlnToCHESSConsole(e.toString()); |
| displayMessage(shell, ERROR_MSG + e.toString(), MessageDialog.ERROR); |
| return null; |
| } |
| } |
| |
| private static String connectToDeem(IFile resultFile, IProgressMonitor monitor){ |
| try{ |
| DEEMClient c = new DEEMClient(); |
| c.setProgressMonitor(monitor); |
| String res = c.sendAndReceiveFile(resultFile.getLocation().toString(), resultFile.getParent().getLocation().toString()); |
| return res; |
| } catch (UnknownHostException e) { |
| e.printStackTrace(); |
| CHESSProjectSupport.printlnToCHESSConsole(e.toString()); |
| displayMessage(shell, ERROR_MSG + e.toString(), MessageDialog.ERROR); |
| return null; |
| } catch (SocketTimeoutException e) { |
| e.printStackTrace(); |
| CHESSProjectSupport.printlnToCHESSConsole(e.toString()); |
| displayMessage(shell, ERROR_MSG + e.toString(), MessageDialog.ERROR); |
| return null; |
| } catch (IOException e) { |
| e.printStackTrace(); |
| CHESSProjectSupport.printlnToCHESSConsole(e.toString()); |
| displayMessage(shell, ERROR_MSG + e.toString(), MessageDialog.ERROR); |
| return null; |
| } catch (ClassNotFoundException e) { |
| e.printStackTrace(); |
| CHESSProjectSupport.printlnToCHESSConsole(e.toString()); |
| displayMessage(shell, ERROR_MSG + e.toString(), MessageDialog.ERROR); |
| return null; |
| } |
| } |
| |
| private void backPropagation(String analysis, PapyrusMultiDiagramEditor editor) { |
| |
| try { |
| String name = null; |
| String value = null; |
| //get data from analysis file |
| FileInputStream fstream = new FileInputStream(analysis); |
| DataInputStream in = new DataInputStream(fstream); |
| BufferedReader br = new BufferedReader(new InputStreamReader(in)); |
| String line; |
| String[] lineSplit; |
| Map<String, String> results = new HashMap<String, String>(); |
| while ((line = br.readLine()) != null){ |
| if(line.startsWith(MEASURE)){ |
| lineSplit = line.split("\\s+"); |
| name = lineSplit[2]; |
| value = lineSplit[3]; |
| if(lineSplit[4].equals("(*)")) { |
| value = value + " " + lineSplit[4]; |
| } |
| |
| results.put(name, value); |
| } |
| } |
| in.close(); |
| |
| if(results.size() > 0) { |
| //get model file |
| Resource res = ResourceUtils.getUMLResource(editor.getServicesRegistry()); |
| Model umlModel = ResourceUtils.getModel(res); |
| |
| //get the CHESS stereotype |
| CHESS chess = (CHESS) umlModel.getStereotypeApplication(umlModel.getAppliedStereotype(CHESS_QN)); |
| //navigate and update the model with the analysis result |
| Package depView = chess.getAnalysisView().getDepanalysisview().getBase_Package(); |
| |
| EList<PackageableElement> packList = depView.getPackagedElements(); |
| Component comp = null; |
| |
| Iterator<String> it = results.keySet().iterator(); |
| String key = null; |
| while(it.hasNext()) { |
| key = it.next(); |
| |
| for (int i = 0 ; i < packList.size(); i++){ |
| if(packList.get(i).getName().equals(key)){ |
| comp = (Component) packList.get(i); |
| } |
| } |
| |
| final String finalValue = results.get(key); |
| final Component com = comp; |
| final Stereotype stereotype = comp.getAppliedStereotype(STATEBASED_ANALYSIS_QN); |
| TransactionalEditingDomain editingDomain = (TransactionalEditingDomain) editor.getEditingDomain(); |
| editingDomain.getCommandStack().execute(new RecordingCommand(editingDomain) { |
| |
| protected void doExecute() { |
| com.setValue(stereotype, RESULT, finalValue); |
| } |
| }); |
| } |
| }else{ |
| System.out.println("Error: Unable to retrieve results from DEEM server."); |
| } |
| |
| } catch (IOException e) { |
| e.printStackTrace(); |
| CHESSProjectSupport.printlnToCHESSConsole(e.toString()); |
| displayMessage(shell, ERROR_MSG + e.toString(), MessageDialog.ERROR); |
| } catch (ServiceException e) { |
| e.printStackTrace(); |
| CHESSProjectSupport.printlnToCHESSConsole(e.toString()); |
| displayMessage(shell, ERROR_MSG + e.toString(), MessageDialog.ERROR); |
| } |
| } |
| |
| //FIXME: not aligned to Luna release (cause: unused) |
| // protected void CallBuildInstances(final PapyrusMultiDiagramEditor editor) { |
| // |
| // try { |
| // //retrieve the diagrams for which the instance have to be rebuildt |
| // Resource notation = ResourceUtils.getNotationResource(editor.getServicesRegistry()); |
| // |
| // EList <EObject> tmp = notation.getContents(); |
| // for (int i = 0; i < tmp.size(); i++){ |
| // Diagram di = (Diagram) tmp.get(i); |
| // if(di.getType().equals("CompositeStructure")){ |
| // Element e = (Element)di.getElement(); |
| // if(e.getAppliedStereotype(RESURCEPLATFORM) != null){ |
| // |
| // final CompositeStructureDiagramEditPart csd_ep = (CompositeStructureDiagramEditPart) di; |
| // TransactionalEditingDomain editingDomain = csd_ep.getEditingDomain(); |
| // editingDomain.getCommandStack().execute( |
| // new RecordingCommand(editingDomain) { |
| // protected void doExecute() { |
| // if (BuildInstanceCommand.buildPrototypeInstanceRestoringAssigns(editor, csd_ep, new StringBuffer()) != null){ |
| // editor.getDiagramStatus().setUserAction(false); |
| // } |
| // } |
| // }); |
| // } |
| // } |
| // } |
| // } catch (Exception e) { |
| // e.printStackTrace(); |
| // CHESSProjectSupport.printlnToCHESSConsole(e.toString()); |
| // } |
| // |
| // } |
| |
| |
| private static String changeSuffix(String str, String oldsfx, String newsfx){ |
| |
| if (str.endsWith(oldsfx)){ |
| str = str.substring(0, str.lastIndexOf(".")); |
| str += newsfx; |
| } |
| return str; |
| } |
| |
| public static void displayMessage(final Shell parent, final String message, final int kind){ |
| |
| final String title = "State-Based Analysis"; |
| parent.getDisplay().syncExec(new Runnable() { |
| @Override |
| public void run() { |
| MessageDialog.open(kind, parent, title, message, SWT.NONE); |
| } |
| }); |
| } |
| } |