Java tutorial
/* * 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’operazione. * * @param monitor Gestore dell’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’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’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’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’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’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’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); } }