| /******************************************************************************* |
| * Copyright (c) 2008-2010 Sonatype, Inc. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Sonatype, Inc. - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.m2e.core.ui.internal.wizards; |
| |
| import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.createElementWithText; |
| import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.findChild; |
| import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.format; |
| import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.getChild; |
| import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.performOnDOMDocument; |
| import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.textEquals; |
| |
| import java.util.Arrays; |
| import java.util.List; |
| import java.util.Properties; |
| |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import org.w3c.dom.Element; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IProject; |
| 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.IStatus; |
| import org.eclipse.core.runtime.jobs.IJobChangeEvent; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.core.runtime.jobs.JobChangeAdapter; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.ui.INewWizard; |
| import org.eclipse.ui.progress.IProgressConstants; |
| |
| import org.apache.maven.archetype.catalog.Archetype; |
| import org.apache.maven.model.Model; |
| import org.apache.maven.model.Parent; |
| |
| import org.eclipse.m2e.core.MavenPlugin; |
| import org.eclipse.m2e.core.ui.internal.MavenImages; |
| import org.eclipse.m2e.core.ui.internal.Messages; |
| import org.eclipse.m2e.core.ui.internal.actions.OpenMavenConsoleAction; |
| import org.eclipse.m2e.core.ui.internal.editing.PomEdits.Operation; |
| import org.eclipse.m2e.core.ui.internal.editing.PomEdits.OperationTuple; |
| |
| |
| /** |
| * A project wizard for creating a new Maven2 module project. |
| */ |
| public class MavenModuleWizard extends AbstractMavenProjectWizard implements INewWizard { |
| private static final Logger LOG = LoggerFactory.getLogger(MavenModuleWizard.class); |
| |
| /** the parent page (#1) */ |
| protected MavenModuleWizardParentPage parentPage; |
| |
| /** The archetype selection page. */ |
| protected MavenProjectWizardArchetypePage archetypePage; |
| |
| /** The wizard page for gathering Maven2 project information. */ |
| protected MavenProjectWizardArtifactPage artifactPage; |
| |
| /** The wizard page for gathering archetype project information. */ |
| protected MavenProjectWizardArchetypeParametersPage parametersPage; |
| |
| private String moduleName; |
| |
| protected boolean isEditor = false; |
| |
| /** Default constructor. Sets the title and image of the wizard. */ |
| public MavenModuleWizard() { |
| setWindowTitle(Messages.wizardModuleTitle); |
| setDefaultPageImageDescriptor(MavenImages.WIZ_NEW_PROJECT); |
| setNeedsProgressMonitor(true); |
| } |
| |
| public MavenModuleWizard(boolean isEditor) { |
| this(); |
| this.isEditor = isEditor; |
| } |
| |
| /** Creates the pages. */ |
| public void addPages() { |
| parentPage = new MavenModuleWizardParentPage(importConfiguration, workingSets); |
| archetypePage = new MavenProjectWizardArchetypePage(importConfiguration); |
| parametersPage = new MavenProjectWizardArchetypeParametersPage(importConfiguration); |
| artifactPage = new MavenProjectWizardArtifactPage(importConfiguration); |
| |
| addPage(parentPage); |
| addPage(archetypePage); |
| addPage(parametersPage); |
| addPage(artifactPage); |
| } |
| |
| /** Adds the listeners after the page controls are created. */ |
| public void createPageControls(Composite pageContainer) { |
| artifactPage.setParentReadonly(true); |
| artifactPage.setTitle(Messages.wizardModulePageArtifactTitle); |
| archetypePage.setTitle(Messages.wizardModulePageArchetypeTitle); |
| parametersPage.setTitle(Messages.wizardModulePageParametersTitle); |
| |
| super.createPageControls(pageContainer); |
| |
| parametersPage.setArtifactIdEnabled(false); |
| |
| parentPage.addArchetypeSelectionListener(new SelectionAdapter() { |
| public void widgetSelected(SelectionEvent e) { |
| boolean isArchetype = !parentPage.isSimpleProject(); |
| archetypePage.setUsed(isArchetype); |
| parametersPage.setUsed(isArchetype); |
| } |
| }); |
| |
| parentPage.addModuleNameListener(e -> { |
| parametersPage.setProjectName(parentPage.getModuleName()); |
| artifactPage.setProjectName(parentPage.getModuleName()); |
| }); |
| |
| parentPage.addParentProjectListener(e -> copyParentValues()); |
| |
| archetypePage.addArchetypeSelectionListener(selectionchangedevent -> { |
| parametersPage.setArchetype(archetypePage.getArchetype()); |
| getContainer().updateButtons(); |
| }); |
| |
| if(selection != null && selection.size() > 0) { |
| parentPage.setParent(selection.getFirstElement()); |
| copyParentValues(); |
| } |
| } |
| |
| /** Copies the parent project parameters to the artifact page. */ |
| protected void copyParentValues() { |
| Model model = parentPage.getParentModel(); |
| if(model != null) { |
| String groupId = model.getGroupId(); |
| String artifactId = model.getArtifactId(); |
| String version = model.getVersion(); |
| |
| if(groupId == null) { |
| Parent parent = model.getParent(); |
| if(parent != null) { |
| groupId = parent.getGroupId(); |
| } |
| } |
| if(version == null) { |
| Parent parent = model.getParent(); |
| if(parent != null) { |
| version = parent.getVersion(); |
| } |
| } |
| |
| artifactPage.setParentProject(groupId, artifactId, version); |
| parametersPage.setParentProject(groupId, artifactId, version); |
| } |
| } |
| |
| /** Performs the "finish" action. */ |
| public boolean performFinish() { |
| // First of all, we extract all the information from the wizard pages. |
| // Note that this should not be done inside the operation we will run |
| // since many of the wizard pages' methods can only be invoked from within |
| // the SWT event dispatcher thread. However, the operation spawns a new |
| // separate thread to perform the actual work, i.e. accessing SWT elements |
| // from within that thread would lead to an exception. |
| |
| final String moduleName = parentPage.getModuleName(); |
| |
| // Get the location where to create the project. For some reason, when using |
| // the default workspace location for a project, we have to pass null |
| // instead of the actual location. |
| final IPath location = parentPage.getParentContainer().getLocation(); |
| |
| final IFile parentPom = parentPage.getPom(); |
| |
| Job job; |
| |
| if(parentPage.isSimpleProject()) { |
| |
| final Model model = artifactPage.getModel(); |
| if(model.getParent() != null) { |
| Parent par = model.getParent(); |
| String relPath = location.makeRelativeTo(location.append(moduleName)).toOSString(); |
| if(!"..".equals(relPath)) { //$NON-NLS-1$ |
| par.setRelativePath(relPath); |
| } |
| |
| //#335331 remove current model's version and groupId if equal to parent, to prevent showing a warning marker |
| if(par.getGroupId() != null && par.getGroupId().equals(model.getGroupId())) { |
| model.setGroupId(null); |
| } |
| if(par.getVersion() != null && par.getVersion().equals(model.getVersion())) { |
| model.setVersion(null); |
| } |
| } |
| |
| final String[] folders = artifactPage.getFolders(); |
| |
| job = new AbstractCreateMavenProjectJob(NLS.bind(Messages.wizardProjectJobCreatingProject, moduleName)) { |
| @Override |
| protected List<IProject> doCreateMavenProjects(IProgressMonitor monitor) throws CoreException { |
| setProperty(IProgressConstants.ACTION_PROPERTY, new OpenMavenConsoleAction()); |
| String projectName = importConfiguration.getProjectName(model); |
| IProject project = importConfiguration.getProject(ResourcesPlugin.getWorkspace().getRoot(), model); |
| |
| // XXX respect parent's setting for separate projects for modules |
| // XXX should run update sources on parent instead of creating new module project |
| |
| MavenPlugin.getProjectConfigurationManager().createSimpleProject(project, location.append(moduleName), model, |
| folders, importConfiguration, new MavenProjectWorkspaceAssigner(workingSets), monitor); |
| |
| setModule(projectName); |
| |
| return Arrays.asList(project); |
| } |
| }; |
| |
| } else { |
| Model model = parametersPage.getModel(); |
| |
| final Archetype archetype = archetypePage.getArchetype(); |
| |
| final String groupId = model.getGroupId(); |
| final String artifactId = model.getArtifactId(); |
| final String version = model.getVersion(); |
| final String javaPackage = parametersPage.getJavaPackage(); |
| final Properties properties = parametersPage.getProperties(); |
| |
| job = new AbstractCreateMavenProjectJob(NLS.bind(Messages.wizardProjectJobCreating, archetype.getArtifactId())) { |
| @Override |
| protected List<IProject> doCreateMavenProjects(IProgressMonitor monitor) throws CoreException { |
| List<IProject> projects = MavenPlugin.getProjectConfigurationManager().createArchetypeProjects(location, |
| archetype, // |
| groupId, artifactId, version, javaPackage, // |
| properties, importConfiguration, new MavenProjectWorkspaceAssigner(workingSets), monitor); |
| |
| setModule(moduleName); |
| |
| return projects; |
| } |
| }; |
| } |
| job.addJobChangeListener(new JobChangeAdapter() { |
| public void done(IJobChangeEvent event) { |
| final IStatus result = event.getResult(); |
| if(result.isOK()) { |
| if(!isEditor) { |
| //add the <module> element to the parent pom |
| try { |
| performOnDOMDocument(new OperationTuple(parentPom, (Operation) document -> { |
| Element root = document.getDocumentElement(); |
| Element modules = getChild(root, "modules"); //$NON-NLS-1$ |
| if(findChild(modules, "module", textEquals(moduleName)) == null) { //$NON-NLS-1$ |
| format(createElementWithText(modules, "module", moduleName)); //$NON-NLS-1$ |
| } |
| })); |
| } catch(Exception e) { |
| LOG.error("Cannot add module to parent POM", e); //$NON-NLS-1$ |
| } |
| } |
| |
| } else { |
| Display.getDefault().asyncExec(() -> MessageDialog.openError(getShell(), // |
| NLS.bind(Messages.wizardProjectJobFailed, moduleName), // |
| result.getMessage())); |
| } |
| } |
| }); |
| job.setRule(MavenPlugin.getProjectConfigurationManager().getRule()); |
| job.schedule(); |
| |
| if(isEditor) { |
| try { |
| job.join(); |
| } catch(InterruptedException ex) { |
| // ignore |
| } |
| } |
| |
| return true; |
| } |
| |
| void setModule(String moduleName) { |
| this.moduleName = moduleName; |
| } |
| |
| public String getModuleName() { |
| return this.moduleName; |
| } |
| } |