package org.overture.ide.plugins.isatrans; import java.io.File; import java.io.IOException; import java.io.PrintStream; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import org.apache.commons.io.FileUtils; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourceAttributes; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.console.ConsolePlugin; import org.eclipse.ui.console.IConsole; import org.eclipse.ui.console.MessageConsole; import org.overture.ast.lex.Dialect; import org.overture.ast.modules.AModuleModules; import org.overture.codegen.utils.GeneratedModule; import org.overture.ide.core.ast.NotAllowedException; import org.overture.ide.core.resources.IVdmProject; import org.overture.ide.ui.utility.VdmTypeCheckerUi; import org.overture.isapog.IsaPog; import org.overturetool.cgisa.IsaGen; public class IsaTransControl { private IWorkbenchWindow window; private IVdmProject proj; private Shell shell; public IsaTransControl(IWorkbenchWindow window, IVdmProject proj, Shell shell) { this.window = window; this.proj = proj; this.shell = shell; } public void generateTheoryFilesModelPos() { final MessageConsole console = new MessageConsole("Isabelle Translation", null); ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[] { console }); console.activate(); console.clearConsole(); PrintStream printStream = new PrintStream(console.newMessageStream()); printStream.println("Starting Isabelle to VDM translation of Model and Proof Obligations..."); printStream.println(); if (!preFlightCheck()) { return; } File isaDir = makeThyDirs(); try { printStream.println("Translating Model and POs."); AModuleModules ast = proj.getModel().getModuleList().get(0); IsaPog ip = new IsaPog(ast); if (ip.getModelThyString().equals("") || ip.getPosThyString().equals("")) { openErrorDialog("Internal error."); // FIXME report errors return; } printStream.println("Copying model source."); backUpModel(isaDir); printStream.println("Writing theory files."); File modelFile = new File(isaDir.getPath() + File.separatorChar + ip.getModelThyName()); FileUtils.writeStringToFile(modelFile, ip.getModelThyString()); File posFile = new File(isaDir.getPath() + File.separatorChar + ip.getPosThyName()); FileUtils.writeStringToFile(posFile, ip.getPosThyString()); refreshProject(); printStream.println(); printStream.println("Model and Proof Obligations Translation complete."); printStream.close(); } catch (Exception e) { openErrorDialog("Internal error."); e.printStackTrace(); } } public void generateTheoryFilesModel() { final MessageConsole console = new MessageConsole("Isabelle Translation", null); ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[] { console }); console.activate(); console.clearConsole(); PrintStream printStream = new PrintStream(console.newMessageStream()); printStream.println("Starting Isabelle to VDM translation of Model..."); printStream.println(); if (!preFlightCheck()) { return; } File isaDir = makeThyDirs(); IsaGen ig = new IsaGen(); try { printStream.println("Translating Model."); List<AModuleModules> ast = proj.getModel().getModuleList(); List<GeneratedModule> modellTheoryList = ig.generateIsabelleSyntax(ast); GeneratedModule modelTheory = modellTheoryList.get(0); if (modelTheory.getContent().isEmpty()) { openErrorDialog("Internal error."); printStream.println(modelTheory.getMergeErrors()); printStream.println(modelTheory.getUnsupportedInIr()); printStream.println(modelTheory.getUnsupportedInTargLang()); return; } printStream.println("Copying model source."); backUpModel(isaDir); printStream.println("Writing theory files."); String thyName = modelTheory.getName() + ".thy"; File thyFile = new File(isaDir.getPath() + File.separatorChar + thyName); FileUtils.writeStringToFile(thyFile, modelTheory.getContent()); refreshProject(); printStream.println(); printStream.println("Model Translation complete."); printStream.close(); } catch (Exception e) { openErrorDialog("Internal error."); e.printStackTrace(); } } private void backUpModel(File isaDir) throws CoreException, IOException { File sourceFile = proj.getSpecFiles().get(0).getSystemFile(); File backupFile = new File(isaDir, sourceFile.getName() + ".bk"); FileUtils.copyFile(sourceFile, backupFile); // Concert to IFile and mark as read-only IWorkspace workspace= ResourcesPlugin.getWorkspace(); IPath location= Path.fromOSString(backupFile.getAbsolutePath()); IFile ifile= workspace.getRoot().getFileForLocation(location); refreshProject(); ResourceAttributes attributes = new ResourceAttributes(); attributes.setReadOnly(true); ifile.setResourceAttributes(attributes); } private void refreshProject() throws CoreException { IProject p = (IProject) proj.getAdapter(IProject.class); p.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor()); } private File makeThyDirs() { DateFormat df = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss"); File isaDir = new File(new File(proj.getModelBuildPath().getOutput().getLocation().toFile(), "Isabelle"), df.format(new Date())); isaDir.mkdirs(); return isaDir; } private boolean preFlightCheck() { if (proj == null) { openErrorDialog("Please select a project before translating"); return false; } if (!VdmTypeCheckerUi.typeCheck(shell, proj)) { openErrorDialog("Model has errors."); return false; } ; if (!proj.getDialect().equals(Dialect.VDM_SL)) { openErrorDialog("Only module VDM-SL models are allowed."); return false; } try { if (proj.getSpecFiles().size() > 1) { openErrorDialog("Only single-file projects are allowed."); return false; } if (proj.getModel().getModuleList().size() > 1) { openErrorDialog("Only single module VDM-SL models are allowed."); return false; } } catch (NotAllowedException | CoreException e) { e.printStackTrace(); } return true; } private void openErrorDialog(String message) { MessageDialog.openError(window.getShell(), "VDM 2 Isabelle", "Cannot generate theory files.\n\n" + message); } }