org.eclipse.m2m.internal.qvt.oml.ui.wizards.project.NewProjectCreationOperation.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.m2m.internal.qvt.oml.ui.wizards.project.NewProjectCreationOperation.java

Source

/*******************************************************************************
 * Copyright (c) 2009, 2014 Borland Software Corporation and others.
 * 
 * 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:
 *     Borland Software Corporation - initial API and implementation
 *     Christopher Gerking - bugs 319078, 414662
 *******************************************************************************/
package org.eclipse.m2m.internal.qvt.oml.ui.wizards.project;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

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.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
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.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.environments.IExecutionEnvironment;
import org.eclipse.jdt.launching.environments.IExecutionEnvironmentsManager;
import org.eclipse.m2m.internal.qvt.oml.ui.QVTUIPlugin;
import org.eclipse.pde.core.plugin.IPluginReference;
import org.eclipse.ui.actions.WorkspaceModifyOperation;

class NewProjectCreationOperation extends WorkspaceModifyOperation {

    private static final String BUNDLE_EXEC_ENV = "J2SE-1.5"; //$NON-NLS-1$

    private static final String BUILD_FILENAME_DESCRIPTOR = "build.properties"; //$NON-NLS-1$

    private static final IPath REQUIRED_PLUGINS_CONTAINER_PATH = new Path("org.eclipse.pde.core.requiredPlugins"); //$NON-NLS-1$

    private static final String PLUGIN_NATURE = "org.eclipse.pde.PluginNature"; //$NON-NLS-1$

    private static Map<String, Integer> fSeverityTable = null;
    private static final int SEVERITY_ERROR = 3;
    private static final int SEVERITY_WARNING = 2;
    private static final int SEVERITY_IGNORE = 1;

    // instance fields
    private PluginClassCodeGenerator fGenerator;

    private NewProjectData fData;

    private IProject fProjectHandle;

    public NewProjectCreationOperation(IProject projectHandle, NewProjectData projectData) {
        if (projectHandle == null || projectData == null) {
            throw new IllegalArgumentException();
        }

        fData = projectData;
        fProjectHandle = projectHandle;
    }

    protected void createContents(IProgressMonitor monitor, IProject project)
            throws CoreException, InterruptedException {
    }

    private void createBuildProperties(IProject project, IProgressMonitor monitor) throws CoreException {
        IFile buildProperties = project.getFile(BUILD_FILENAME_DESCRIPTOR);
        StringWriter contents = new StringWriter();
        PrintWriter wr = new PrintWriter(contents, true);

        if (fData.isCreateJava()) {
            IPath sourceFolder = asBinIncludesFolder(createJavaFolder(fData.getSourceFolderName(), monitor));
            IPath outFolder = asBinIncludesFolder(createJavaFolder(fData.getOutFolderName(), monitor));

            wr.append("source.. = ").println(sourceFolder.toString()); //$NON-NLS-1$
            wr.append("output.. = ").println(outFolder.toString()); //$NON-NLS-1$
        }

        char[] alignChars = new char[15];
        Arrays.fill(alignChars, ' ');
        String indent = new String(alignChars);

        wr.print("bin.includes = META-INF/"); //$NON-NLS-1$
        if (fData.isCreateJava()) {
            wr.println(",\\"); //$NON-NLS-1$
            wr.append(indent).append('.');
        }

        IContainer qvtContainer = createJavaFolder(fData.getQVTSourceFolderName(), monitor);
        IPath qvtFolder = asBinIncludesFolder(qvtContainer);
        if (!fProjectHandle.equals(qvtContainer) || !fData.isCreateJava()) {
            wr.println(",\\"); //$NON-NLS-1$
            wr.append(indent).append(qvtFolder.toString());
        }

        wr.println();
        wr.flush();

        InputStream is = createContentStreamForNewFile(buildProperties, contents.getBuffer().toString());
        buildProperties.create(is, false, monitor);
    }

    private void createManifest(IFolder metaFolder, IProgressMonitor monitor) throws CoreException {
        IFile manifest = metaFolder.getFile("MANIFEST.MF"); //$NON-NLS-1$
        StringWriter contents = new StringWriter();
        PrintWriter wr = new PrintWriter(contents, true);

        wr.println("Manifest-Version: 1.0"); //$NON-NLS-1$
        wr.println("Bundle-ManifestVersion: 2"); //$NON-NLS-1$
        wr.append("Bundle-Name: ").println(fData.getName()); //$NON-NLS-1$
        wr.append("Bundle-SymbolicName: ").println(fData.getID()); //$NON-NLS-1$
        wr.append("Bundle-Version: ").println(fData.getVersion()); //$NON-NLS-1$
        wr.append("Bundle-Vendor: ").println(fData.getProviderName()); //$NON-NLS-1$

        IPluginReference[] dependencies = getDependencies();
        if (dependencies.length > 0) {
            wr.append("Require-Bundle:"); //$NON-NLS-1$

            int i = 0;
            for (IPluginReference pluginReference : dependencies) {
                if (i++ > 0) {
                    wr.println(',');
                }
                wr.append(' ');
                wr.append(pluginReference.getId());
            }
            wr.println();
        }

        if (fData.isCreateJava() && getEEnv(BUNDLE_EXEC_ENV) != null) {
            wr.append("Bundle-RequiredExecutionEnvironment: ").println(BUNDLE_EXEC_ENV); //$NON-NLS-1$
        }

        wr.flush();

        InputStream is = createContentStreamForNewFile(manifest, contents.getBuffer().toString());
        manifest.create(is, false, monitor);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.actions.WorkspaceModifyOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
     */
    @Override
    protected void execute(IProgressMonitor monitor)
            throws CoreException, InvocationTargetException, InterruptedException {
        SubMonitor progress = SubMonitor.convert(monitor, Messages.NewProjectCreationOperation_createQVTProjectTask,
                2);

        createProject(progress.newChild(1));
        createContents(progress.newChild(1), fProjectHandle);

        monitor.done();
    }

    private void generateTopLevelPluginClass(IProgressMonitor monitor) throws CoreException {
        fGenerator.generate(monitor);
        monitor.done();
    }

    private IPluginReference[] getDependencies() {
        if (fGenerator == null) {
            return new IPluginReference[0];
        }
        return fGenerator.getDependencies();
    }

    private void setupJava(IProject project, boolean pde, IProgressMonitor monitor)
            throws CoreException, JavaModelException {
        addNatureToProject(project, JavaCore.NATURE_ID, monitor);

        IContainer srcContainer = createJavaFolder(fData.getSourceFolderName(), monitor);
        IContainer binContainer = createJavaFolder(fData.getOutFolderName(), monitor);

        IJavaProject javaProject = JavaCore.create(project);
        javaProject.setOutputLocation(binContainer.getFullPath(), monitor);

        monitor.subTask(Messages.NewProjectCreationOperation_SetClassPathTask);

        IClasspathEntry[] entries = new IClasspathEntry[pde ? 3 : 1];
        if (pde) {
            String executionEnvironment = BUNDLE_EXEC_ENV;
            setComplianceOptions(javaProject, executionEnvironment, true);
            entries[0] = createJREEntry(executionEnvironment);
            entries[1] = createContainerEntry();
        }

        entries[entries.length - 1] = JavaCore.newSourceEntry(srcContainer.getFullPath());
        javaProject.setRawClasspath(entries, monitor);

        if (fData.isDoGenerateClass()) {
            generateTopLevelPluginClass(new SubProgressMonitor(monitor, 1));
        }

        monitor.worked(1);
    }

    private void createProject(IProgressMonitor monitor) throws CoreException, JavaModelException {
        SubMonitor subMonitor = SubMonitor.convert(monitor, 7);

        URI location = URIUtil.toURI(fData.getLocation());

        IWorkspace workspace = ResourcesPlugin.getWorkspace();
        final IProjectDescription description = workspace.newProjectDescription(fProjectHandle.getName());
        if (location != null && ResourcesPlugin.getWorkspace().getRoot().getLocationURI().equals(location)) {
            location = null;
        }
        description.setLocationURI(location);

        if (!fProjectHandle.exists()) {
            fProjectHandle.create(description, subMonitor.newChild(1));
        }
        subMonitor.setWorkRemaining(6);

        if (subMonitor.isCanceled()) {
            throw new OperationCanceledException();
        }

        fProjectHandle.open(IResource.BACKGROUND_REFRESH, subMonitor.newChild(1));

        if (fData.isPlugin()) {
            addNatureToProject(fProjectHandle, PLUGIN_NATURE, subMonitor.newChild(1));

            fGenerator = new PluginClassCodeGenerator(fProjectHandle, fData);

            if (fData.isCreateJava()) {
                setupJava(fProjectHandle, true, subMonitor.newChild(1));
            }
            subMonitor.setWorkRemaining(3);

            // generate the manifest file
            IFolder metaFolder = fProjectHandle.getFolder("META-INF"); //$NON-NLS-1$
            metaFolder.create(true, true, subMonitor.newChild(1));

            createManifest(metaFolder, subMonitor.newChild(1));

            // generate the build.properties file
            createBuildProperties(fProjectHandle, subMonitor.newChild(1));

        } else if (fData.isCreateJava()) {
            subMonitor.setWorkRemaining(1);
            setupJava(fProjectHandle, false, subMonitor.newChild(1));
        }
    }

    private void addNatureToProject(IProject proj, String natureId, IProgressMonitor monitor) throws CoreException {
        IProjectDescription description = proj.getDescription();
        String[] prevNatures = description.getNatureIds();
        String[] newNatures = new String[prevNatures.length + 1];
        System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length);
        newNatures[prevNatures.length] = natureId;
        description.setNatureIds(newNatures);
        proj.setDescription(description, monitor);
    }

    /**
     * Returns a classpath container entry for the given execution environment.
     * @param ee id of the execution environment
     * @return classpath container entry
     */
    private static IClasspathEntry createJREEntry(String ee) {
        return JavaCore.newContainerEntry(getEEPath(ee));
    }

    /**
     * Returns the JRE container path for the execution environment with the given id.
     * @param ee execution environment id
     * @return JRE container path for the execution environment
     */
    private static IPath getEEPath(String ee) {
        IPath path = null;
        if (ee != null) {
            IExecutionEnvironment env = getEEnv(ee);
            if (env != null)
                path = JavaRuntime.newJREContainerPath(env);
        }
        if (path == null) {
            path = JavaRuntime.newDefaultJREContainerPath();
        }
        return path;
    }

    private static IExecutionEnvironment getEEnv(String ee) {
        if (ee != null) {
            IExecutionEnvironmentsManager manager = JavaRuntime.getExecutionEnvironmentsManager();
            return manager.getEnvironment(ee);
        }
        return null;
    }

    private static IClasspathEntry createContainerEntry() {
        return JavaCore.newContainerEntry(REQUIRED_PLUGINS_CONTAINER_PATH);
    }

    @SuppressWarnings("unchecked")
    private static void setComplianceOptions(IJavaProject project, String eeId, boolean overrideExisting) {
        Map<String, String> projectMap = project.getOptions(false);
        IExecutionEnvironment ee = null;
        Map<String, String> options = null;
        if (eeId != null) {
            ee = JavaRuntime.getExecutionEnvironmentsManager().getEnvironment(eeId);
            if (ee != null) {
                options = ee.getComplianceOptions();
            }
        }
        if (options == null) {
            if (overrideExisting && projectMap.size() > 0) {
                projectMap.remove(JavaCore.COMPILER_COMPLIANCE);
                projectMap.remove(JavaCore.COMPILER_SOURCE);
                projectMap.remove(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM);
                projectMap.remove(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER);
                projectMap.remove(JavaCore.COMPILER_PB_ENUM_IDENTIFIER);
            } else {
                return;
            }
        } else {
            String compliance = options.get(JavaCore.COMPILER_COMPLIANCE);
            Iterator<?> iterator = options.entrySet().iterator();
            while (iterator.hasNext()) {
                Entry<?, ?> entry = (Entry<?, ?>) iterator.next();
                String option = (String) entry.getKey();
                String value = (String) entry.getValue();
                if (JavaCore.VERSION_1_3.equals(compliance) || JavaCore.VERSION_1_4.equals(compliance)) {
                    if (JavaCore.COMPILER_PB_ASSERT_IDENTIFIER.equals(option)
                            || JavaCore.COMPILER_PB_ENUM_IDENTIFIER.equals(option)) {
                        // for 1.3 & 1.4 projects, only override the existing setting if the default setting
                        // is a greater severity than the existing setting
                        setMinimumCompliance(projectMap, option, value, overrideExisting);
                    } else {
                        setCompliance(projectMap, option, value, overrideExisting);
                    }
                } else {
                    setCompliance(projectMap, option, value, overrideExisting);
                }
            }
        }

        project.setOptions(projectMap);
    }

    private static void setMinimumCompliance(Map<String, String> map, String key, String minimumValue,
            boolean override) {
        if (minimumValue != null && (override || !map.containsKey(key))) {
            if (fSeverityTable == null) {
                fSeverityTable = new HashMap<String, Integer>(3);
                fSeverityTable.put(JavaCore.IGNORE, new Integer(SEVERITY_IGNORE));
                fSeverityTable.put(JavaCore.WARNING, new Integer(SEVERITY_WARNING));
                fSeverityTable.put(JavaCore.ERROR, new Integer(SEVERITY_ERROR));
            }
            String currentValue = (String) map.get(key);
            int current = currentValue != null && fSeverityTable.containsKey(currentValue)
                    ? ((Integer) fSeverityTable.get(currentValue)).intValue()
                    : 0;
            int minimum = minimumValue != null && fSeverityTable.containsKey(minimumValue)
                    ? ((Integer) fSeverityTable.get(minimumValue)).intValue()
                    : 0;
            if (current < minimum) {
                map.put(key, minimumValue);
            }
        }
    }

    private static void setCompliance(Map<String, String> map, String key, String value, boolean override) {
        if (value != null && (override || !map.containsKey(key))) {
            map.put(key, value);
        }
    }

    private InputStream createContentStreamForNewFile(IFile fileHandle, String contents) {
        String charset = null;
        try {
            charset = fileHandle.getProject().getDefaultCharset();
        } catch (CoreException e) {
            QVTUIPlugin.log(e.getStatus());
        }

        if (charset == null) {
            charset = ResourcesPlugin.getEncoding();
        }

        byte[] bytes;
        try {
            bytes = contents.getBytes(charset);
        } catch (UnsupportedEncodingException e) {
            bytes = contents.getBytes();
        }

        return new ByteArrayInputStream(bytes);
    }

    private IPath asBinIncludesFolder(IContainer container) {
        if (container.equals(fProjectHandle)) {
            return new Path("."); //$NON-NLS-1$
        }
        IPath result = container.getProjectRelativePath();
        while (result.hasTrailingSeparator()) {
            result = result.removeTrailingSeparator();
        }
        // ensure single trailing slash
        return result.addTrailingSeparator();
    }

    private IContainer createJavaFolder(String folderName, IProgressMonitor monitor) throws CoreException {
        if (folderName == null || folderName.trim().length() == 0) {
            return fProjectHandle;
        }

        IFolder folder = fProjectHandle.getFolder(folderName);
        if (!folder.exists()) {
            folder.create(true, true, monitor);
        }
        return folder;
    }
}