org.eclipse.imp.java.hosted.wizards.NewProjectWizardSecondPage.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.imp.java.hosted.wizards.NewProjectWizardSecondPage.java

Source

/*******************************************************************************
* Copyright (c) 2007 IBM Corporation.
* 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:
*    Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
*******************************************************************************/

package org.eclipse.imp.java.hosted.wizards;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.resources.IContainer;
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.resources.IResourceStatus;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceDescription;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
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.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.imp.builder.ProjectNatureBase;
import org.eclipse.imp.runtime.RuntimePlugin;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.ui.wizards.ClassPathDetector;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.IVMInstall2;
import org.eclipse.jdt.launching.IVMInstallType;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jdt.ui.PreferenceConstants;
import org.eclipse.jdt.ui.wizards.JavaCapabilityConfigurationPage;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.WorkspaceModifyDelegatingOperation;
import org.eclipse.ui.ide.IDE;

public abstract class NewProjectWizardSecondPage extends JavaCapabilityConfigurationPage {
    private static final String FILENAME_PROJECT = ".project"; //$NON-NLS-1$
    private static final String FILENAME_CLASSPATH = ".classpath"; //$NON-NLS-1$

    private final NewProjectWizardFirstPage fFirstPage;

    private URI fCurrProjectLocation; // null if location is platform location

    private IProject fCurrProject;

    private boolean fKeepContent;

    private File fDotProjectBackup;
    private File fDotClasspathBackup;

    private Boolean fIsAutobuild = null;

    /**
     * @return the IProjectNature to add to the newly-created project
     */
    protected abstract ProjectNatureBase getProjectNature();

    /**
     * Sub-classes may override if they need to contribute only one classpath entry to the
     * new project. In that case, they should not override createLanguageRuntimeEntries()
     * as well.
     * @return the IClasspathEntry for the language-specific runtime (jar, whatever) that
     * will be placed in the new project's classpath.
     * This used to return an IPath, but this class would always create a "variable"
     * classpath entry, which is not always appropriate. We now let the language-specific
     * implementation decide what kind of classpath entry to create.
     */
    protected IClasspathEntry createLanguageRuntimeEntry() {
        return null;
    }

    /**
     * Sub-classes may override if they need to contribute multiple classpath entries to the
     * new project. If they do, they shouldn't also override createLanguageRuntimeEntry().
     * The default implementation returns whatever createLanguageRuntimeEntry() returns.
     * @return the list of IClasspathEntry's for the language-specific runtime components
     * (jars, whatever) that will be placed in the new project's classpath.
     */
    protected List<IClasspathEntry> createLanguageRuntimeEntries() {
        IClasspathEntry uniqueEntry = createLanguageRuntimeEntry();

        if (uniqueEntry != null) {
            return Arrays.asList(uniqueEntry);
        }
        return Collections.emptyList();
    }

    public NewProjectWizardSecondPage(NewProjectWizardFirstPage firstPage) {
        super();
        fFirstPage = firstPage;
    }

    /**
     * Called from the wizard on finish.
     */
    public void performFinish(IProgressMonitor monitor) throws CoreException, InterruptedException {
        try {
            //monitor.beginTask(NewWizardMessages.JavaProjectWizardSecondPage_operation_create, 3);  // <= 3.3
            //monitor.beginTask(NewWizardMessages.NewJavaProjectWizardPageTwo_operation_create, 3);    // >= 3.4
            monitor.beginTask("Creating project...", 3);
            if (fCurrProject == null) {
                updateProject(new SubProgressMonitor(monitor, 1));
            }
            configureJavaProject(new SubProgressMonitor(monitor, 2));
            String compliance = fFirstPage.getJRECompliance();
            if (compliance != null) {
                IJavaProject project = JavaCore.create(fCurrProject);
                Map<String, String> options = project.getOptions(false);

                JavaCore.setComplianceOptions(compliance, options);
                project.setOptions(options);
            }
        } finally {
            monitor.done();
            fCurrProject = null;
            if (fIsAutobuild != null) {
                enableAutoBuild(fIsAutobuild.booleanValue());
                fIsAutobuild = null;
            }
        }
    }

    /**
     * Set the autobuild to the value of the parameter and
     * return the old one.
     * 
     * @param state the value to be set for autobuilding.
     * @return the old value of the autobuild state
     */
    public static boolean enableAutoBuild(boolean state) throws CoreException {
        IWorkspace workspace = ResourcesPlugin.getWorkspace();
        IWorkspaceDescription desc = workspace.getDescription();
        boolean isAutoBuilding = desc.isAutoBuilding();
        if (isAutoBuilding != state) {
            desc.setAutoBuilding(state);
            workspace.setDescription(desc);
        }
        return isAutoBuilding;
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.dialogs.IDialogPage#setVisible(boolean)
     */
    public void setVisible(boolean visible) {
        if (visible) {
            IStatus status = changeToNewProject();
            if (status != null && !status.isOK()) {
                ErrorDialog.openError(getShell(),
                        //NewWizardMessages.JavaProjectWizardSecondPage_error_title,
                        "New Java Project", null, status);
            }
        } else {
            removeProject();
        }
        super.setVisible(visible);
        if (visible) {

            setFocus();
        }
    }

    private IStatus changeToNewProject() {
        fKeepContent = fFirstPage.getDetect();

        class UpdateRunnable implements IRunnableWithProgress {
            public IStatus infoStatus = Status.OK_STATUS;

            public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
                try {
                    if (fIsAutobuild == null) {
                        fIsAutobuild = Boolean.valueOf(enableAutoBuild(false));
                    }
                    infoStatus = updateProject(monitor);
                } catch (CoreException e) {
                    throw new InvocationTargetException(e);
                } catch (OperationCanceledException e) {
                    throw new InterruptedException();
                } finally {
                    monitor.done();
                }
            }
        }
        UpdateRunnable op = new UpdateRunnable();
        try {
            getContainer().run(true, false, new WorkspaceModifyDelegatingOperation(op));
            return op.infoStatus;
        } catch (InvocationTargetException e) {
            final String title = "New Java Project"; //NewWizardMessages.JavaProjectWizardSecondPage_error_title; 
            final String message = "An error occurred while creating project. Check log for details."; //NewWizardMessages.JavaProjectWizardSecondPage_error_message; 
            perform(e, getShell(), title, message);
        } catch (InterruptedException e) {
            // cancel pressed
        }
        return null;
    }

    protected void perform(CoreException e, Shell shell, String title, String message) {
        RuntimePlugin.getInstance().logException(message, e);
        IStatus status = e.getStatus();
        if (status != null) {
            ErrorDialog.openError(shell, title, message, status);
        } else {
            displayMessageDialog(e, e.getMessage(), shell, title, message);
        }
    }

    protected void perform(InvocationTargetException e, Shell shell, String title, String message) {
        Throwable target = e.getTargetException();
        if (target instanceof CoreException) {
            perform((CoreException) target, shell, title, message);
        } else {
            RuntimePlugin.getInstance().logException(message, e);
            if (e.getMessage() != null && e.getMessage().length() > 0) {
                displayMessageDialog(e, e.getMessage(), shell, title, message);
            } else {
                displayMessageDialog(e, target.getMessage(), shell, title, message);
            }
        }
    }

    private void displayMessageDialog(Throwable t, String exceptionMessage, Shell shell, String title,
            String message) {
        StringWriter msg = new StringWriter();
        if (message != null) {
            msg.write(message);
            msg.write("\n\n"); //$NON-NLS-1$
        }
        if (exceptionMessage == null || exceptionMessage.length() == 0)
            msg.write("See the Error Log for more details.");
        else
            msg.write(exceptionMessage);
        MessageDialog.openError(shell, title, msg.toString());
    }

    final IStatus updateProject(IProgressMonitor monitor) throws CoreException, InterruptedException {
        IStatus result = new Status(IStatus.OK, RuntimePlugin.IMP_RUNTIME, "Ok");

        fCurrProject = fFirstPage.getProjectHandle();
        fCurrProjectLocation = getProjectLocationURI();

        if (monitor == null) {
            monitor = new NullProgressMonitor();
        }
        try {
            monitor.beginTask("Initializing project...", 7);
            if (monitor.isCanceled()) {
                throw new OperationCanceledException();
            }

            URI realLocation = fCurrProjectLocation;
            if (fCurrProjectLocation == null) { // inside workspace
                try {
                    URI rootLocation = ResourcesPlugin.getWorkspace().getRoot().getLocationURI();
                    realLocation = new URI(rootLocation.getScheme(), null, Path
                            .fromPortableString(rootLocation.getPath()).append(fCurrProject.getName()).toString(),
                            null);
                } catch (URISyntaxException e) {
                    Assert.isTrue(false, "Can't happen"); //$NON-NLS-1$
                }
            }

            rememberExistingFiles(realLocation);

            try {
                createProject(fCurrProject, fCurrProjectLocation, new SubProgressMonitor(monitor, 2));
            } catch (CoreException e) {
                if (e.getStatus().getCode() == IResourceStatus.FAILED_READ_METADATA) {
                    result = new Status(IStatus.INFO, RuntimePlugin.IMP_RUNTIME, MessageFormat.format(
                            "A problem occurred while creating the project from existing source:\n\n''{0}''\n\nThe corrupt project file will be replaced by a valid one.",
                            e.getLocalizedMessage()));

                    deleteProjectFile(realLocation);
                    if (fCurrProject.exists())
                        fCurrProject.delete(true, null);

                    createProject(fCurrProject, fCurrProjectLocation, null);
                } else {
                    throw e;
                }
            }

            IClasspathEntry[] entries = null;
            IPath outputLocation = null;

            if (fFirstPage.getDetect()) {
                if (!fCurrProject.getFile(FILENAME_CLASSPATH).exists()) {
                    final ClassPathDetector detector = new ClassPathDetector(fCurrProject,
                            new SubProgressMonitor(monitor, 2));
                    entries = detector.getClasspath();
                    outputLocation = detector.getOutputLocation();
                } else {
                    monitor.worked(2);
                }
            } else if (fFirstPage.isSrcBin()) {
                IPreferenceStore store = PreferenceConstants.getPreferenceStore();
                IPath srcPath = new Path(store.getString(PreferenceConstants.SRCBIN_SRCNAME));
                IPath binPath = new Path(store.getString(PreferenceConstants.SRCBIN_BINNAME));

                if (srcPath.segmentCount() > 0) {
                    IFolder folder = fCurrProject.getFolder(srcPath);
                    createFolder(folder, true, true, new SubProgressMonitor(monitor, 1));
                } else {
                    monitor.worked(1);
                }

                if (binPath.segmentCount() > 0 && !binPath.equals(srcPath)) {
                    IFolder folder = fCurrProject.getFolder(binPath);
                    createDerivedFolder(folder, true, true, new SubProgressMonitor(monitor, 1));
                } else {
                    monitor.worked(1);
                }

                final IPath projectPath = fCurrProject.getFullPath();

                // configure the classpath entries, including the default jre library.
                List<IClasspathEntry> cpEntries = new ArrayList<IClasspathEntry>();
                cpEntries.add(JavaCore.newSourceEntry(projectPath.append(srcPath)));
                cpEntries.addAll(Arrays.asList(getDefaultClasspathEntry()));
                entries = (IClasspathEntry[]) cpEntries.toArray(new IClasspathEntry[cpEntries.size()]);

                // configure the output location
                outputLocation = projectPath.append(binPath);
            } else {
                IPath projectPath = fCurrProject.getFullPath();
                List<IClasspathEntry> cpEntries = new ArrayList<IClasspathEntry>();
                cpEntries.add(JavaCore.newSourceEntry(projectPath));
                cpEntries.addAll(Arrays.asList(getDefaultClasspathEntry()));
                entries = (IClasspathEntry[]) cpEntries.toArray(new IClasspathEntry[cpEntries.size()]);

                outputLocation = projectPath;
                monitor.worked(2);
            }
            if (monitor.isCanceled()) {
                throw new OperationCanceledException();
            }

            init(JavaCore.create(fCurrProject), outputLocation, entries, false);
            configureJavaProject(new SubProgressMonitor(monitor, 3)); // create the Java project to allow the use of the new source folder page
            getProjectNature().addToProject(fCurrProject);
        } finally {
            monitor.done();
        }
        return result;
    }

    /**
     * Creates a folder and all parent folders if not existing.
     * Project must exist.
     * <code> org.eclipse.ui.dialogs.ContainerGenerator</code> is too heavy
     * (creates a runnable)
     */
    public static void createFolder(IFolder folder, boolean force, boolean local, IProgressMonitor monitor)
            throws CoreException {
        if (!folder.exists()) {
            IContainer parent = folder.getParent();
            if (parent instanceof IFolder) {
                createFolder((IFolder) parent, force, local, null);
            }
            folder.create(force, local, monitor);
        }
    }

    public static void createDerivedFolder(IFolder folder, boolean force, boolean local, IProgressMonitor monitor)
            throws CoreException {
        if (!folder.exists()) {
            IContainer parent = folder.getParent();
            if (parent instanceof IFolder) {
                createDerivedFolder((IFolder) parent, force, local, null);
            }
            folder.create(force ? (IResource.FORCE | IResource.DERIVED) : IResource.DERIVED, local, monitor);
        }
    }

    private URI getProjectLocationURI() throws CoreException {
        if (fFirstPage.isInWorkspace()) {
            return null;
        }
        return URIUtil.toURI(fFirstPage.getLocationPath());
    }

    private void deleteProjectFile(URI projectLocation) throws CoreException {
        IFileStore file = EFS.getStore(projectLocation);
        if (file.fetchInfo().exists()) {
            IFileStore projectFile = file.getChild(FILENAME_PROJECT);
            if (projectFile.fetchInfo().exists()) {
                projectFile.delete(EFS.NONE, null);
            }
        }
    }

    private void rememberExistingFiles(URI projectLocation) throws CoreException {
        fDotProjectBackup = null;
        fDotClasspathBackup = null;

        IFileStore file = EFS.getStore(projectLocation);
        if (file.fetchInfo().exists()) {
            IFileStore projectFile = file.getChild(FILENAME_PROJECT);
            if (projectFile.fetchInfo().exists()) {
                fDotProjectBackup = createBackup(projectFile, "project-desc"); //$NON-NLS-1$ 
            }
            IFileStore classpathFile = file.getChild(FILENAME_CLASSPATH);
            if (classpathFile.fetchInfo().exists()) {
                fDotClasspathBackup = createBackup(classpathFile, "classpath-desc"); //$NON-NLS-1$ 
            }
        }
    }

    private void restoreExistingFiles(URI projectLocation, IProgressMonitor monitor) throws CoreException {
        int ticks = ((fDotProjectBackup != null ? 1 : 0) + (fDotClasspathBackup != null ? 1 : 0)) * 2;
        monitor.beginTask("", ticks); //$NON-NLS-1$
        try {
            IFileStore projectFile = EFS.getStore(projectLocation).getChild(FILENAME_PROJECT);
            projectFile.delete(EFS.NONE, new SubProgressMonitor(monitor, 1));
            if (fDotProjectBackup != null) {
                copyFile(fDotProjectBackup, projectFile, new SubProgressMonitor(monitor, 1));
            }
        } catch (IOException e) {
            IStatus status = new Status(IStatus.ERROR, JavaUI.ID_PLUGIN, IStatus.ERROR,
                    //NewWizardMessages.JavaProjectWizardSecondPage_problem_restore_project,
                    "Problem while restoring backup for .project", e);
            throw new CoreException(status);
        }
        try {
            IFileStore classpathFile = EFS.getStore(projectLocation).getChild(FILENAME_CLASSPATH);
            classpathFile.delete(EFS.NONE, new SubProgressMonitor(monitor, 1));
            if (fDotClasspathBackup != null) {
                copyFile(fDotClasspathBackup, classpathFile, new SubProgressMonitor(monitor, 1));
            }
        } catch (IOException e) {
            IStatus status = new Status(IStatus.ERROR, JavaUI.ID_PLUGIN, IStatus.ERROR,
                    //NewWizardMessages.JavaProjectWizardSecondPage_problem_restore_classpath,
                    "Problem while restoring backup for .classpath", e);
            throw new CoreException(status);
        }
    }

    private File createBackup(IFileStore source, String name) throws CoreException {
        try {
            File bak = File.createTempFile("eclipse-" + name, ".bak"); //$NON-NLS-1$//$NON-NLS-2$
            copyFile(source, bak);
            return bak;
        } catch (IOException e) {
            IStatus status = new Status(IStatus.ERROR, JavaUI.ID_PLUGIN, IStatus.ERROR, MessageFormat.format(
                    //NewWizardMessages.JavaProjectWizardSecondPage_problem_backup,
                    "Problem while creating backup for ''{0}''", name), e);
            throw new CoreException(status);
        }
    }

    private void copyFile(IFileStore source, File target) throws IOException, CoreException {
        InputStream is = source.openInputStream(EFS.NONE, null);
        FileOutputStream os = new FileOutputStream(target);
        copyFile(is, os);
    }

    private void copyFile(File source, IFileStore target, IProgressMonitor monitor)
            throws IOException, CoreException {
        FileInputStream is = new FileInputStream(source);
        OutputStream os = target.openOutputStream(EFS.NONE, monitor);
        copyFile(is, os);
    }

    private void copyFile(InputStream is, OutputStream os) throws IOException {
        try {
            byte[] buffer = new byte[8192];
            while (true) {
                int bytesRead = is.read(buffer);
                if (bytesRead == -1)
                    break;

                os.write(buffer, 0, bytesRead);
            }
        } finally {
            try {
                is.close();
            } finally {
                os.close();
            }
        }
    }

    private IClasspathEntry[] getDefaultClasspathEntry() {
        // First create a classpath entry for the language-specific runtime
        List<IClasspathEntry> cpEntries = new ArrayList<IClasspathEntry>();
        List<IClasspathEntry> langRuntimeCPEs = createLanguageRuntimeEntries();

        if (langRuntimeCPEs != null) {
            cpEntries.addAll(langRuntimeCPEs);
        }

        // Now try to find a compatible JRE
        String compliance = fFirstPage.getJRECompliance();
        IVMInstall inst = findMatchingJREInstall(compliance);
        IPath jreContainerPath = new Path(JavaRuntime.JRE_CONTAINER);

        if (inst != null) {
            IPath newPath = jreContainerPath.append(inst.getVMInstallType().getId()).append(inst.getName());
            IClasspathEntry jreCPE = JavaCore.newContainerEntry(newPath);
            cpEntries.add(jreCPE);
        } else {
            // Didn't find a compatible JRE; use the default
            IClasspathEntry[] defaultJRELibrary = PreferenceConstants.getDefaultJRELibrary();

            for (int i = 0; i < defaultJRELibrary.length; i++) {
                cpEntries.add(defaultJRELibrary[i]);
            }
        }
        return cpEntries.toArray(new IClasspathEntry[cpEntries.size()]);
    }

    private IVMInstall findMatchingJREInstall(String compliance) {
        IVMInstallType vmInstallType = JavaRuntime.getVMInstallTypes()[0];
        IVMInstall[] vmInstalls = vmInstallType.getVMInstalls();

        for (int i = 0; i < vmInstalls.length; i++) {
            if (vmInstalls[i] instanceof IVMInstall2) {
                IVMInstall2 vmInstall2 = (IVMInstall2) vmInstalls[i];
                String vmVers = vmInstall2.getJavaVersion();

                if (vmVers.startsWith(compliance)) {
                    return vmInstalls[i];
                }
            }
        }
        return null;
    }

    private void removeProject() {
        if (fCurrProject == null || !fCurrProject.exists()) {
            return;
        }

        IRunnableWithProgress op = new IRunnableWithProgress() {
            public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
                doRemoveProject(monitor);
            }
        };

        try {
            getContainer().run(true, true, new WorkspaceModifyDelegatingOperation(op));
        } catch (InvocationTargetException e) {
            final String title = //NewWizardMessages.JavaProjectWizardSecondPage_error_remove_title; 
                    "Error Creating Java Project";
            final String message = //NewWizardMessages.JavaProjectWizardSecondPage_error_remove_message; 
                    "An error occurred while removing a temporary project.";
            perform(e, getShell(), title, message);
        } catch (InterruptedException e) {
            // cancel pressed
        }
    }

    final void doRemoveProject(IProgressMonitor monitor) throws InvocationTargetException {
        final boolean noProgressMonitor = (fCurrProjectLocation == null); // inside workspace
        if (monitor == null || noProgressMonitor) {
            monitor = new NullProgressMonitor();
        }
        monitor.beginTask( //NewWizardMessages.JavaProjectWizardSecondPage_operation_remove,
                "Removing project...", 3);
        try {
            try {
                URI projLoc = fCurrProject.getLocationURI();

                boolean removeContent = !fKeepContent && fCurrProject.isSynchronized(IResource.DEPTH_INFINITE);
                fCurrProject.delete(removeContent, false, new SubProgressMonitor(monitor, 2));

                restoreExistingFiles(projLoc, new SubProgressMonitor(monitor, 1));
            } finally {
                enableAutoBuild(fIsAutobuild.booleanValue()); // fIsAutobuild must be set
                fIsAutobuild = null;
            }
        } catch (CoreException e) {
            throw new InvocationTargetException(e);
        } finally {
            monitor.done();
            fCurrProject = null;
            fKeepContent = false;
        }
    }

    protected void openResource(final IFile resource) {
        Display.getDefault().asyncExec(new Runnable() {
            public void run() {
                final IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
                        .getActivePage();
                if (activePage != null) {
                    final Display display = getShell().getDisplay();
                    if (display != null) {
                        display.asyncExec(new Runnable() {
                            public void run() {
                                try {
                                    IDE.openEditor(activePage, resource, true);
                                } catch (PartInitException e) {
                                    RuntimePlugin.getInstance().getLog()
                                            .log(new Status(IStatus.ERROR, RuntimePlugin.IMP_RUNTIME,
                                                    "Error opening editor on newly-created source file", e));
                                }
                            }
                        });
                    }
                }
            }
        });
    }
}