/******************************************************************************* * Copyright (c) 2009-2015 CWI * 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-v10.html * * Contributors: * * Jurgen J. Vinju - Jurgen.Vinju@cwi.nl - CWI * * Arnold Lankamp - Arnold.Lankamp@cwi.nl * * Michael Steindorfer - Michael.Steindorfer@cwi.nl - CWI * * Anya Helene Bagge - anya@ii.uib.no - UiB *******************************************************************************/ package org.rascalmpl.eclipse.wizards; import java.io.IOException; import java.io.OutputStream; import java.lang.reflect.InvocationTargetException; import java.nio.charset.Charset; import java.util.List; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.Wizard; import org.eclipse.ui.INewWizard; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.ide.IDE; import org.rascalmpl.eclipse.Activator; import org.rascalmpl.eclipse.IRascalResources; import org.rascalmpl.eclipse.util.RascalEclipseManifest; import org.rascalmpl.eclipse.util.RascalKeywords; import org.rascalmpl.uri.ProjectURIResolver; import org.rascalmpl.uri.URIResolverRegistry; import io.usethesource.vallang.ISourceLocation; public class NewRascalFile extends Wizard implements INewWizard { private NewRascalFilePage page; private ISelection selection; private String moduleName; public NewRascalFile() { super(); setNeedsProgressMonitor(true); setWindowTitle("Create a new Rascal module file"); } @Override public void addPages() { page = new NewRascalFilePage(selection); addPage(page); } @Override public boolean performFinish() { String container = page.getContainerName(); if (container.endsWith("/")) { container = container.substring(0, container.length() - 1); } final String containerName = container; final String filename = page.getFileName(); IRunnableWithProgress op = new IRunnableWithProgress() { @Override public void run(IProgressMonitor monitor) throws InvocationTargetException { try { IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); IPath path = new Path(containerName); IProject project = root.getFolder(path).getProject(); int till = containerName.substring(1).indexOf("/"); String containerToPutFileIn = containerName; String fileToCreate = filename; if(till != -1){ containerToPutFileIn = containerName.substring(0, till + 1); fileToCreate = containerName.substring(till + 1) + "/" + filename; } fileToCreate = fileToCreate.endsWith(".rsc") ? fileToCreate : fileToCreate + ".rsc"; List<String> srcs = new RascalEclipseManifest().getSourceRoots(project); moduleName = fileToCreate; for (String src : srcs) { if (moduleName.startsWith("/" + src)) { moduleName = moduleName.substring(src.length() + 1); break; } } moduleName = moduleName.substring(0, moduleName.length() - 4); moduleName = moduleName.replaceAll("/", "::"); moduleName = moduleName.startsWith("::") ? moduleName.substring(2) : moduleName; moduleName = moduleName.startsWith("src::") ? moduleName.substring(5) : moduleName; moduleName = RascalKeywords.escapeName(moduleName); doFinish(containerToPutFileIn, fileToCreate, monitor); } catch (CoreException e) { throw new InvocationTargetException(e); } finally { monitor.done(); } } }; try { getContainer().run(true, false, op); } catch (InterruptedException e) { return false; } catch (InvocationTargetException e) { Throwable realException = e.getTargetException(); MessageDialog.openError(getShell(), "Error", realException.getMessage()); return false; } return true; } private void doFinish( String containerName, String fileName, IProgressMonitor monitor) throws CoreException { // create a sample file monitor.beginTask("Creating " + fileName, 2); IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); Path path = new Path(containerName); IResource resource = path.segmentCount() > 1 ? root.getProject(path.segment(0)).getFolder(path.removeFirstSegments(1)) : root.getProject(path.segment(0)); if (!resource.exists() || !(resource instanceof IContainer)) { throwCoreException("Container \"" + containerName + "\" does not exist."); } IContainer container = (IContainer) resource; final IFile file = container.getFile(new Path(fileName)); ISourceLocation loc = ProjectURIResolver.constructProjectURI(file.getFullPath()); try (OutputStream out = URIResolverRegistry.getInstance().getOutputStream(loc, false)) { out.write(("module "+moduleName).getBytes(Charset.forName("UTF8"))); monitor.worked(1); monitor.setTaskName("Opening file for editing..."); getShell().getDisplay().asyncExec(new Runnable() { @Override public void run() { IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); try { IDE.openEditor(page, file, true); } catch (PartInitException e) { } } }); monitor.worked(1); } catch (IOException e) { Activator.log("could not create new Rascal module", e); } } private void throwCoreException(String message) throws CoreException { IStatus status = new Status(IStatus.ERROR, IRascalResources.ID_RASCAL_ECLIPSE_PLUGIN, IStatus.OK, message, null); throw new CoreException(status); } @Override public void init(IWorkbench workbench, IStructuredSelection selection) { this.selection = selection; } }