/** * <copyright> * </copyright> * * */ package org.dresdenocl.language.ocl.resource.ocl.ui; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.eclipse.core.resources.ICommand; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.ui.ISelectionService; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.IWorkingSet; import org.eclipse.ui.IWorkingSetManager; import org.eclipse.ui.PlatformUI; import org.osgi.framework.Bundle; /** * This class is used to create an example project via the new dialog of Eclipse. * The contents of the example project are obtained from a ZIP file named * <code>newProject.zip</code> that must be located in the resource.ui plug-in. If * not such ZIP file can be found, an empty project containing an example file of * the DSL is created. */ public class OclNewProjectWizardLogic { /** * Creates the example project by unzipping the contents of * <code>newProjectZip</code>. */ public void createExampleProject(IProgressMonitor monitor, IPath projectPath, String projectName, String bundleName, String newProjectZip) throws InterruptedException { try { monitor.beginTask(getTaskName(), 120); // Create the project folder String projectFolder = projectPath.toOSString() + File.separator + projectName; File projectFolderFile = new File(projectFolder); IWorkspace workspace = ResourcesPlugin.getWorkspace(); IProject project = workspace.getRoot().getProject(projectName); // If the project does not exist, we will create it and populate it. if (!project.exists()) { projectFolderFile.mkdirs(); monitor.worked(10); Bundle bundle = Platform.getBundle(bundleName); URL newProjectZipURL = bundle.getEntry(newProjectZip); if (newProjectZipURL != null) { // Copy plug-in project code extractProject(projectFolderFile, newProjectZipURL, new SubProgressMonitor(monitor, 100)); } if (monitor.isCanceled()) { throw new InterruptedException(); } IProjectDescription desc = workspace.newProjectDescription(project.getName()); if (!projectPath.equals(workspace.getRoot().getLocation())) { desc.setLocation(new Path(projectFolder)); } String natureID = org.dresdenocl.language.ocl.resource.ocl.mopp.OclNature.NATURE_ID; List<ICommand> buildCommands = new ArrayList<ICommand>(); for (String builderID : org.dresdenocl.language.ocl.resource.ocl.mopp.OclNature.BUILDER_IDS) { ICommand command = desc.newCommand(); command.setBuilderName(builderID); buildCommands.add(command); } desc.setNatureIds(new String[] {natureID}); desc.setBuildSpec(buildCommands.toArray(new ICommand[buildCommands.size()])); addProjectToSelectedWorkingSet(project); project.create(desc, monitor); // Now, we ensure that the project is open. project.open(monitor); renameProject(project, projectName); createDefaultNewFile(project, newProjectZipURL == null); } monitor.worked(10); if (monitor.isCanceled()) { throw new InterruptedException(); } } catch (IOException e) { throw new RuntimeException(e); } catch (CoreException e) { throw new RuntimeException(e); } finally { monitor.done(); } } /** * <p> * Adds the newly created project to the currently selected working set. * </p> * * @param project the project to be added to the selected working set */ private void addProjectToSelectedWorkingSet(IProject project) { IWorkbench workbench = PlatformUI.getWorkbench(); IWorkbenchWindow workbenchWindow = workbench.getActiveWorkbenchWindow(); if (workbenchWindow == null) { return; } ISelectionService selectionService = workbenchWindow.getSelectionService(); ISelection selection = selectionService.getSelection(); if (selection instanceof IStructuredSelection) { IStructuredSelection structuredSelection = (IStructuredSelection) selection; Object firstElement = structuredSelection.getFirstElement(); if (firstElement instanceof IAdaptable) { IAdaptable adaptable = (IAdaptable) firstElement; IWorkingSet workingSet = (IWorkingSet) adaptable.getAdapter(IWorkingSet.class); if (workingSet != null) { // new project wizard was invoked by right-clicking a working set IWorkingSetManager workingSetManager = workbench.getWorkingSetManager(); workingSetManager.addToWorkingSets(project, new IWorkingSet[]{workingSet}); } } } } /** * <p> * Unzip the project archive to the specified folder * </p> * * @param projectFolderFile The folder where to unzip the project archive * @param monitor Monitor to display progress and/or cancel operation * * @throws IOException * * @throws InterruptedException * * @throws FileNotFoundException */ private void extractProject(File projectFolderFile, URL url, IProgressMonitor monitor) throws FileNotFoundException, IOException, InterruptedException { // Get project archive URL urlZipLocal = FileLocator.toFileURL(url); // Walk each element and unzip ZipFile zipFile = new ZipFile(urlZipLocal.getPath()); try { // Allow for a hundred work units monitor.beginTask("Extracting Project", zipFile.size()); unzip(zipFile, projectFolderFile, monitor); } finally { zipFile.close(); monitor.done(); } } /** * <p> * Unzips the platform formatted zip file to specified folder * </p> * * @param zipFile The platform formatted zip file * @param projectFolderFile The folder where to unzip the project archive * @param monitor Monitor to display progress and/or cancel operation * * @throws IOException * * @throws FileNotFoundException * * @throws InterruptedException */ protected void unzip(ZipFile zipFile, File projectFolderFile, IProgressMonitor monitor) throws IOException, FileNotFoundException, InterruptedException { Enumeration<? extends ZipEntry> e = zipFile.entries(); while (e.hasMoreElements()) { ZipEntry zipEntry = (ZipEntry) e.nextElement(); File file = new File(projectFolderFile, zipEntry.getName()); if (zipEntry.isDirectory()) { file.mkdirs(); } else { // Copy files (and make sure parent directory exist) File parentFile = file.getParentFile(); if (null != parentFile && false == parentFile.exists()) { parentFile.mkdirs(); } Path path = new Path(file.getPath()); if ("java".equals(path.getFileExtension())) { InputStreamReader is = null; OutputStreamWriter os = null; try { is = new InputStreamReader(zipFile.getInputStream(zipEntry), "ISO-8859-1"); os = new OutputStreamWriter(new FileOutputStream(file), ResourcesPlugin.getEncoding()); char[] buffer = new char[102400]; while (true) { int len = is.read(buffer); if (len < 0) { break; } os.write(buffer, 0, len); } } finally { if (null != is) { is.close(); } if (null != os) { os.close(); } } } else { InputStream is = null; OutputStream os = null; try { is = zipFile.getInputStream(zipEntry); os = new FileOutputStream(file); byte[] buffer = new byte[102400]; while (true) { int len = is.read(buffer); if (len < 0) { break; } os.write(buffer, 0, len); } } finally { if (null != is) { is.close(); } if (null != os) { os.close(); } } } } monitor.worked(1); if (monitor.isCanceled()) { throw new InterruptedException(); } } } /** * <p> * Renames the specified project to the specified name. * </p> * * @param project a project to rename * @param projectName a new name for the project * * @throws CoreException if something goes wrong */ protected void renameProject(IProject project, String projectName) throws CoreException { IProjectDescription description = project.getDescription(); description.setName(projectName); } protected String getTaskName() { return "Creating Example Project"; } protected void createDefaultNewFile(IProject project, boolean createDefaultNewFile) throws CoreException { IFile defaultNewFile = project.getFile("NEW_FILE_PLACEHOLDER"); if (createDefaultNewFile) { defaultNewFile.create(new ByteArrayInputStream(new byte[0]), true, null); } if (defaultNewFile.exists()) { org.dresdenocl.language.ocl.resource.ocl.mopp.OclMetaInformation info = new org.dresdenocl.language.ocl.resource.ocl.mopp.OclMetaInformation(); String fileName = "new_file." + info.getSyntaxName(); String content = info.getNewFileContentProvider().getNewFileContent("new_file." + info.getSyntaxName()); defaultNewFile.setContents(new ByteArrayInputStream(content.getBytes()), IFile.FORCE, null); defaultNewFile.move(project.getProjectRelativePath().append(fileName), true, null); } } }