it.scoppelletti.sdk.ide.ui.NewWebProjectOperation.java Source code

Java tutorial

Introduction

Here is the source code for it.scoppelletti.sdk.ide.ui.NewWebProjectOperation.java

Source

/*
 * Copyright (C) 2010 Dario Scoppelletti, <http://www.scoppelletti.it/>.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package it.scoppelletti.sdk.ide.ui;

import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.launching.*;
import org.eclipse.jem.workbench.utility.*;
import org.eclipse.jst.common.project.facet.core.*;
import org.eclipse.jst.j2ee.project.facet.*;
import org.eclipse.wst.common.componentcore.*;
import org.eclipse.wst.common.componentcore.resources.*;
import org.eclipse.wst.common.project.facet.core.*;
import it.scoppelletti.sdk.ide.*;
import it.scoppelletti.sdk.ide.projects.*;

/**
 * Operazione di creazione di un nuovo progetto di applicazione Web.
 */
final class NewWebProjectOperation extends NewProjectOperationBase {
    private static final String MODULE_TEMPLATE = "template_module2.txt";
    private static final String BUILD_TEMPLATE = "template_build.txt";
    private static final String LOCAL_TEMPLATE = "template_local2.txt";
    private static final String WEB_TEMPLATE = "template_web.txt";
    private static final String DEPLOY_TEMPLATE = "template_deploy.txt";
    private static final String MVC_TEMPLATE = "template_mvc.txt";
    private static final String CONTEXT_TEMPLATE = "template_context.txt";

    /**
     * Costruttore.
     * 
     * @param params Parametri.
     */
    NewWebProjectOperation(INewProjectParameters params) {
        super(params);
    }

    /**
     * Esegue l&rsquo;operazione.
     * 
     * @param monitor Gestore dell&rsquo;avanzamento.
     */
    @Override
    protected void execute(IProgressMonitor monitor)
            throws CoreException, InvocationTargetException, InterruptedException {
        IProject project;
        IJavaProject javaProject;
        IFacetedProject facetedProject;
        SubMonitor progress;

        progress = SubMonitor.convert(monitor, "Creating...", 9);

        try {
            project = createProject(progress.newChild(1));
            progress.worked(1);

            facetedProject = createFacetedProject(project, progress.newChild(1));
            progress.worked(1);

            javaProject = createJavaProject(project, progress.newChild(1));
            progress.worked(1);

            createOutputFolder(javaProject, progress.newChild(1));
            progress.worked(1);

            setNatures(project, progress.newChild(1));
            progress.worked(1);

            setFacets(facetedProject, progress.newChild(1));
            progress.worked(1);

            createFolders(project, progress.newChild(1));
            progress.worked(1);

            createFiles(project, progress.newChild(1));
            progress.worked(1);

            setClasspath(javaProject, progress.newChild(1));
            progress.worked(1);
        } finally {
            if (monitor != null) {
                monitor.done();
            }
        }
    }

    /**
     * Crea il direttorio di output.
     * 
     * @param project Progetto.
     * @param monitor Gestore dell&rsquo;avanzamento.
     */
    private void createOutputFolder(IJavaProject project, IProgressMonitor monitor) throws CoreException {
        IFolder outputFolder;
        ProjectDirectory projectDir;
        SubMonitor progress;

        progress = SubMonitor.convert(monitor, "Creating the output folder...", 2);

        try {
            projectDir = new ProjectDirectory(project.getProject());
            outputFolder = projectDir.getBuildWebClassesFolder();
            createFolder(outputFolder, progress.newChild(1));
            progress.worked(1);

            // Imposto il direttorio del bytecode in modo che l'impostazione del
            // facet jst.web lo rilevi correttamente                            
            project.setOutputLocation(outputFolder.getFullPath(), progress.newChild(1));
            progress.worked(1);
        } finally {
            if (monitor != null) {
                monitor.done();
            }
        }
    }

    /**
     * Imposta le nature del progetto.
     * 
     * @param project Progetto.
     * @param monitor Gestore dell&rsquo;avanzamento.
     */
    @SuppressWarnings("restriction")
    private void setNatures(IProject project, IProgressMonitor monitor) throws CoreException {
        SubMonitor progress;

        progress = SubMonitor.convert(monitor, "Setting project natures...", 2);
        try {
            addProjectNature(project, ModuleCoreNature.MODULE_NATURE_ID, progress.newChild(1));
            progress.worked(1);

            addProjectNature(project, IJavaEMFNature.NATURE_ID, progress.newChild(1));
            progress.worked(1);
        } finally {
            if (monitor != null) {
                monitor.done();
            }
        }
    }

    /**
     * Imposta i facet del progetto.
     * 
     * @param project Progetto.
     * @param monitor Gestore dell&rsquo;avanzamento.
     */
    private void setFacets(IFacetedProject project, IProgressMonitor monitor) throws CoreException {
        IProjectFacetVersion javaFacet, webFacet;
        Set<IProjectFacet> fixedFacets;
        SubMonitor progress;

        progress = SubMonitor.convert(monitor, "Setting project facets...", 3);

        try {
            javaFacet = JavaFacet.VERSION_1_6; // java
            webFacet = IJ2EEFacetConstants.DYNAMIC_WEB_30; // jst.web

            project.installProjectFacet(javaFacet, null, progress.newChild(1));
            progress.worked(1);

            project.installProjectFacet(webFacet, null, progress.newChild(1));
            progress.worked(1);

            fixedFacets = new HashSet<IProjectFacet>();
            fixedFacets.add(javaFacet.getProjectFacet());
            fixedFacets.add(webFacet.getProjectFacet());
            project.setFixedProjectFacets(fixedFacets);
            progress.worked(1);

            // La versione 3.0 del facet jst.web fa inserire nel progetto anche
            // la cartella virtuale JAX-WS Web Services.

            // Almeno dalla versione 3.6.1, sul progetto viene installato come
            // obbligatorio anche il facet wst.jsdt.web (JavaScript) che a sua
            // volta imposta la natura org.eclipse.wst.jsdt.core.jsNature, la
            // quale imposta il builder
            // org.eclipse.wst.jsdt.core.javascriptValidator e inserisce la
            // libreria "JavaScript Resources".
            // Nelle versioni precedenti, la natura 
            // org.eclipse.wst.jsdt.core.jsNature.era impostata anche dal facet
            // jst.web, ma riuscivo a rimuoverla (metodo statico removeJsNature
            // della classe JsNature).
            // Il problema e' che in nel presente metodo il facet wst.jsdt.web
            // non risulta ancora installato nel progetto (quindi non lo posso
            // disistallare con il metodo uninstallProjectFacet dell'oggetto
            // project), quindi deve intervenire qualche "aggiustamento" del
            // progetto in seguito.
            // Per il momento, lascio perdere, tanto puo' darsi che utilizzero'
            // anche JavaScript nelle pagine JSP.
        } finally {
            if (monitor != null) {
                monitor.done();
            }
        }
    }

    /**
     * Crea la struttura dei direttori.
     * 
     * @param project Progetto.
     * @param monitor Gestione dell&rsquo;avanzamento.
     */
    @SuppressWarnings("restriction")
    private void createFolders(IProject project, IProgressMonitor monitor) throws CoreException {
        IPath path;
        IFolder folder, javaFolder, resourcesFolder, webContentFolder;
        IVirtualComponent comp;
        IVirtualFolder webRoot;
        IVirtualFolder binFolder;
        ProjectDirectory projectDir;
        SubMonitor progress;

        progress = SubMonitor.convert(monitor, "Creating the directory tree...", 12);

        try {
            comp = ComponentCore.createComponent(project, false);
            comp.create(0, progress.newChild(1));
            progress.worked(1);

            // Il facet jst.web crea il sotto-direttorio WebContent (ma potrebbe 
            // essere prevista una configurazione) come direttorio sorgente dei
            // contenuti Web: 
            // Rimuovo il sotto-direttorio del progetto. 
            //
            // WebContent
            //     |
            //     +-- META-INF
            //     |      |
            //     |      +----- MANIFEST.MF
            //     |
            //     +-- WEB-INF
            //            |
            //            +----- web.xml
            //            |
            //            +----- lib
            //
            webRoot = comp.getRootFolder();
            path = webRoot.getProjectRelativePath();
            if (path != null) {
                webRoot.removeLink(path, 0, progress.newChild(1));
                progress.worked(1);

                path = path.makeRelative();
                if (!path.isEmpty()) {
                    folder = project.getFolder(path);
                    folder.delete(true, false, progress.newChild(1));
                }
                progress.worked(1);
            } else {
                progress.worked(2);
            }

            // Ho appena cancellato un sotto-direttorio creato dal facet
            // jst.web, e non posso prevedere le eventuali relazioni tra questo
            // e il layout dei direttori di progetto di Programmer Power:
            // Creo adesso la struttura del direttorio di progetto sperando che
            // almeno con il direttorio di output (che ho gia' dovuto creare
            // prima) non ci siano problemi. 
            projectDir = new ProjectDirectory(project);

            javaFolder = projectDir.getSourceJavaFolder();
            createFolder(javaFolder, progress.newChild(1));
            progress.worked(1);

            resourcesFolder = projectDir.getSourceResourcesFolder();
            createFolder(resourcesFolder, progress.newChild(1));
            progress.worked(1);

            createFolder(projectDir.getSourceEtcFolder(), progress.newChild(1));
            progress.worked(1);

            webContentFolder = projectDir.getSourceWebContentFolder();
            createFolder(webContentFolder, progress.newChild(1));
            progress.worked(1);

            createFolder(projectDir.getSourceWebMetadataFolder(), progress.newChild(1));
            progress.worked(1);

            createFolder(projectDir.getModuleFolder(), progress.newChild(1));
            progress.worked(1);

            // Imposto il direttorio sorgente dei contenuti Web secondo il
            // layout dei direttori di progetto di Programmer Power
            path = Path.ROOT.append(webContentFolder.getProjectRelativePath());
            webRoot.createLink(path, 0, progress.newChild(1));
            progress.worked(1);

            binFolder = webRoot.getFolder("WEB-INF/classes");
            path = resourcesFolder.getProjectRelativePath();
            binFolder.createLink(path, 0, progress.newChild(1));
            progress.worked(1);

            // Almeno dalla versione 3.6.1, devo ricollegare il direttorio
            // virtuale del bytecode al direttorio dei sorgenti Java
            // (probabilmente viene scollegato dal precedente collegamento dal
            // direttorio dei sorgenti delle risorse).
            path = javaFolder.getProjectRelativePath();
            binFolder.createLink(path, 0, progress.newChild(1));
            progress.worked(1);

            // Imposto il context-root
            comp.setMetaProperty(ModuleCoreNature.CONTEXTROOT, getParams().getBaseName());
        } finally {
            if (monitor != null) {
                monitor.done();
            }
        }
    }

    /**
     * Crea i file.
     * 
     * @param project Progetto.
     * @param monitor Gestore dell&rsquo;avanzamento.
     */
    private void createFiles(IProject project, IProgressMonitor monitor) throws CoreException {
        String contents;
        ProjectDirectory projectDir;
        SubMonitor progress;

        progress = SubMonitor.convert(monitor, "Creating the files...", 16);

        try {
            projectDir = new ProjectDirectory(project);

            contents = buildFilteredContents(NewWebProjectOperation.MODULE_TEMPLATE, progress.newChild(1));
            progress.worked(1);

            createFile(projectDir.getModuleMetadataFile(), contents, progress.newChild(1));
            progress.worked(1);

            contents = buildManifest(progress.newChild(1));
            progress.worked(1);

            createFile(projectDir.getManifestFile(), contents, progress.newChild(1));
            progress.worked(1);

            contents = buildFilteredContents(NewWebProjectOperation.BUILD_TEMPLATE, progress.newChild(1));
            progress.worked(1);

            createFile(projectDir.getBuildFile(), contents, progress.newChild(1));
            progress.worked(1);

            contents = buildFilteredContents(NewWebProjectOperation.LOCAL_TEMPLATE, progress.newChild(1));
            progress.worked(1);

            createFile(projectDir.getEtcLocalFile(), contents, progress.newChild(1));
            progress.worked(1);

            contents = buildFilteredContents(NewWebProjectOperation.WEB_TEMPLATE, progress.newChild(1));
            progress.worked(1);

            createFile(projectDir.getWebMetadataFile(), contents, progress.newChild(1));
            progress.worked(1);

            contents = buildFilteredContents(NewWebProjectOperation.DEPLOY_TEMPLATE, progress.newChild(1));
            progress.worked(1);

            createFile(projectDir.getDeployFile(), contents, progress.newChild(1));
            progress.worked(1);

            contents = buildFilteredContents(NewWebProjectOperation.MVC_TEMPLATE, progress.newChild(1));
            progress.worked(1);

            createFile(projectDir.getMvcConfigFile(), contents, progress.newChild(1));
            progress.worked(1);

            contents = buildFilteredContents(NewWebProjectOperation.CONTEXT_TEMPLATE, progress.newChild(1));
            progress.worked(1);

            createFile(projectDir.getWebContextFile(), contents, progress.newChild(1));
            progress.worked(1);
        } catch (IOException ex) {
            throw new CoreException(StatusUtils.toStatus(ex));
        } finally {
            if (monitor != null) {
                monitor.done();
            }
        }
    }

    /**
     * Imposta il class-path.
     * 
     * @param project Progetto.
     * @param monitor Gestione dell&rsquo;avanzamento.
     */
    private void setClasspath(IJavaProject project, IProgressMonitor monitor)
            throws CoreException, JavaModelException {
        IPath path;
        IFolder sourceFolder;
        IClasspathEntry[] classpath = new IClasspathEntry[3];
        ProjectDirectory projectDir;

        projectDir = new ProjectDirectory(project.getProject());

        // Il facet jst.web inserisce anche i seguenti class-path:
        // 1) org.eclipse.jst.j2ee.internal.web.container
        // 2) org.eclipse.jst.j2ee.internal.module.container 

        sourceFolder = projectDir.getSourceJavaFolder();
        classpath[0] = JavaCore.newSourceEntry(sourceFolder.getFullPath());

        path = JavaRuntime.newDefaultJREContainerPath();
        classpath[1] = JavaCore.newContainerEntry(path);

        classpath[2] = JavaCore.newContainerEntry(DependenciesContainer.PATH);

        project.setRawClasspath(classpath, monitor);
    }
}