package uk.ac.ed.inf.biopepa.ui.wizards.export; import java.io.ByteArrayInputStream; import java.io.InputStream; import org.eclipse.core.resources.*; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.jface.wizard.Wizard; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.events.*; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.*; import org.eclipse.ui.dialogs.SaveAsDialog; import uk.ac.ed.inf.biopepa.core.sba.LineStringBuilder; import uk.ac.ed.inf.biopepa.core.sba.export.PrismExport; import uk.ac.ed.inf.biopepa.ui.interfaces.BioPEPAModel; import uk.ac.ed.inf.biopepa.ui.interfaces.IResourceProvider; public class PrismExportWizard extends Wizard implements IResourceProvider { BioPEPAModel model; private ExportPage exportPage; public PrismExportWizard(BioPEPAModel model) { if(model == null) throw new NullPointerException("Error; model does not exist."); this.model = model; setHelpAvailable(false); setWindowTitle("Export options for Bio-PEPA"); } private class ExportPage extends WizardPage { private Text levelSizeText; private IPath cslPath; private Button setPropertiesFile; private Label cslFileLabel; private Button outputCslCheckButton; protected ExportPage(String pageName) { super(pageName); this.setTitle("Prism CTMC Export"); this.setDescription("Translate the biopepa model into a Prism model"); this.cslPath = null; } public IPath getCSLPath(){ return this.cslPath; } public boolean getOutputCsl(){ return outputCslCheckButton.getSelection(); } public void createControl(Composite parent) { int textStyle = SWT.RIGHT | SWT.BORDER; int labelStyle = SWT.SINGLE | SWT.LEFT; Composite composite = new Composite(parent, SWT.NONE); composite.setLayout(new GridLayout()); setControl(composite); /* Just a small label to say what to do */ Label tmpLabel = new Label(composite, labelStyle); tmpLabel.setText("Please set the level size for this translation"); tmpLabel.setLayoutData(createDefaultGridData()); // Create an inner composite for the labels and text fields Composite labelsComposite = new Composite(composite, SWT.NONE); GridLayout labelsCompLayout = new GridLayout(2, false); labelsComposite.setLayout(labelsCompLayout); Label levelsLabel = new Label (labelsComposite, labelStyle); levelsLabel.setText("Level size: (default 1)"); levelSizeText = new Text(labelsComposite, textStyle); // levelSizeText.setSize(80, 1); levelSizeText.setLayoutData(newTextGridData()); levelSizeText.setText(""); levelSizeText.addModifyListener(modifyListener); setPropertiesFile = new Button (labelsComposite, SWT.PUSH); setPropertiesFile.setText("Set .csl"); setPropertiesFile.setEnabled(true); class SetCSL implements SelectionListener { public void widgetSelected(SelectionEvent event) { setCSLFile(); } public void widgetDefaultSelected(SelectionEvent event) { } } setPropertiesFile.addSelectionListener(new SetCSL()); cslFileLabel = new Label (labelsComposite, labelStyle); cslFileLabel.setText("No file set"); outputCslCheckButton = new Button (labelsComposite, SWT.CHECK); outputCslCheckButton.setText("Output csl properties file"); outputCslCheckButton.setSelection(true); validate(); } /* * A simple method to create a grid data object for * text object, since I think it is better to create a * new one for each text object such that any changes are * not then global. */ private GridData newTextGridData (){ GridData textGridData = new GridData (); textGridData.widthHint = 80; textGridData.horizontalAlignment = GridData.FILL; textGridData.grabExcessHorizontalSpace = true; return textGridData; } private ModifyListener modifyListener = new ModifyListener (){ public void modifyText(ModifyEvent arg0) { validate (); } }; private void validate() { this.setPageComplete(false); this.setErrorMessage(null); String lText = levelSizeText.getText().trim(); try{ if (!lText.isEmpty()){ Integer.parseInt(lText); } } catch (Exception e){ this.setPageComplete(false); this.setErrorMessage("Cannot parse level size"); return ; } this.setPageComplete(true); } public int getLevelSize(){ String text = levelSizeText.getText().trim(); if (text.isEmpty()){ return 1; } try{ return Integer.parseInt(text); } catch (Exception e) { return 1; } } private GridData createDefaultGridData() { /* ...with grabbing horizontal space */ return new GridData(SWT.FILL, SWT.CENTER, true, false); } private boolean setCSLFile() { SaveAsDialog saveAsDialog = new SaveAsDialog(getShell()); IPath path = model.getUnderlyingResource().getFullPath(); path = path.removeFileExtension().addFileExtension("csl"); IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path); saveAsDialog.setOriginalFile(file); saveAsDialog.open(); path = saveAsDialog.getResult(); this.cslPath = path; String label = ".../" + path.lastSegment(); if (label.length() > 30){ label = label.substring(0,25) + "..."; } this.setPropertiesFile.setText("Change:"); this.cslFileLabel.setText(label); return true; } } public void addPages (){ exportPage = new ExportPage("Export a Traviando Trace"); addPage (exportPage); } @Override public boolean performFinish() { SaveAsDialog saveAsDialog = new SaveAsDialog(getShell()); IPath path = model.getUnderlyingResource().getFullPath(); path = path.removeFileExtension().addFileExtension("pm"); IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path); saveAsDialog.setOriginalFile(file); saveAsDialog.open(); path = saveAsDialog.getResult(); if(path == null) return false; path = path.removeFileExtension().addFileExtension("pm"); file = ResourcesPlugin.getWorkspace().getRoot().getFile(path); // Get the csl path from the export page // but if it returns null (ie. it's not been set) // then just make a default based on the .pm file IPath propsPath = exportPage.getCSLPath(); if (propsPath == null){ propsPath = path.removeFileExtension().addFileExtension("csl"); } IFile propsFile = ResourcesPlugin.getWorkspace().getRoot().getFile(propsPath); LineStringBuilder prismLsb = new LineStringBuilder (); LineStringBuilder propsLsb = new LineStringBuilder (); try { int levelSize = exportPage.getLevelSize(); PrismExport pexport = new PrismExport (); pexport.setLevelSize(levelSize); pexport.setModel(model.getCompiledModel()); pexport.setModel(model.getSBAModel()); pexport.export(prismLsb, propsLsb); } catch(Exception e) { e.printStackTrace(); return false; } byte[] prismBuf = prismLsb.toString().getBytes(); InputStream prismSource = new ByteArrayInputStream(prismBuf); byte[] propsBuf = propsLsb.toString().getBytes(); InputStream propsSource = new ByteArrayInputStream (propsBuf); try { // First the prism file if(file.exists()) { file.setContents(prismSource, IResource.NONE, null); } else { file.create(prismSource, IResource.NONE, null); } file.refreshLocal(0, null); if (exportPage.getOutputCsl()) { if (propsFile.exists()) { propsFile.setContents(propsSource, IResource.NONE, null); } else { propsFile.create(propsSource, IResource.NONE, null); } propsFile.refreshLocal(0, null); } } catch(CoreException e) { e.printStackTrace(); return false; } return true; } public IResource getUnderlyingResource() { return model.getUnderlyingResource(); } }