/******************************************************************************* * Copyright (c) 2012-2017 Codenvy, S.A. * 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: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.ide.projecttype.wizard.presenter; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; import org.eclipse.che.api.core.model.project.NewProjectConfig; import org.eclipse.che.api.project.shared.dto.AttributeDto; import org.eclipse.che.api.project.shared.dto.ProjectTypeDto; import org.eclipse.che.api.project.templates.shared.dto.ProjectTemplateDescriptor; import org.eclipse.che.commons.annotation.Nullable; import org.eclipse.che.ide.api.dialogs.DialogFactory; import org.eclipse.che.ide.api.project.MutableProjectConfig; import org.eclipse.che.ide.api.project.NewProjectConfigImpl; import org.eclipse.che.ide.api.project.type.wizard.ProjectWizardMode; import org.eclipse.che.ide.api.project.type.wizard.ProjectWizardRegistrar; import org.eclipse.che.ide.api.project.type.wizard.ProjectWizardRegistry; import org.eclipse.che.ide.api.wizard.Wizard; import org.eclipse.che.ide.api.wizard.WizardPage; import org.eclipse.che.ide.projecttype.wizard.ProjectWizard; import org.eclipse.che.ide.projecttype.wizard.ProjectWizardFactory; import org.eclipse.che.ide.projecttype.wizard.categoriespage.CategoriesPagePresenter; import org.eclipse.che.ide.resource.Path; import javax.validation.constraints.NotNull; import java.util.HashMap; import java.util.List; import java.util.Map; import static org.eclipse.che.ide.api.project.type.wizard.ProjectWizardMode.CREATE; import static org.eclipse.che.ide.api.project.type.wizard.ProjectWizardMode.IMPORT; import static org.eclipse.che.ide.api.project.type.wizard.ProjectWizardMode.UPDATE; /** * Presenter for project wizard. * * @author Evgen Vidolob * @author Oleksii Orel * @author Sergii Leschenko * @author Artem Zatsarynnyi * @author Vlad Zhukovskyi */ @Singleton public class ProjectWizardPresenter implements Wizard.UpdateDelegate, ProjectWizardView.ActionDelegate, CategoriesPagePresenter.ProjectTypeSelectionListener, CategoriesPagePresenter.ProjectTemplateSelectionListener { private final ProjectWizardView view; private final ProjectWizardFactory projectWizardFactory; private final ProjectWizardRegistry wizardRegistry; private final Provider<CategoriesPagePresenter> categoriesPageProvider; private final DialogFactory dialogFactory; private final Map<ProjectTypeDto, ProjectWizard> wizardsCache; private CategoriesPagePresenter categoriesPage; private ProjectWizard wizard; private ProjectWizard importWizard; private WizardPage currentPage; private ProjectWizardMode wizardMode; @Inject public ProjectWizardPresenter(ProjectWizardView view, ProjectWizardFactory projectWizardFactory, ProjectWizardRegistry wizardRegistry, Provider<CategoriesPagePresenter> categoriesPageProvider, DialogFactory dialogFactory) { this.view = view; this.projectWizardFactory = projectWizardFactory; this.wizardRegistry = wizardRegistry; this.categoriesPageProvider = categoriesPageProvider; this.dialogFactory = dialogFactory; wizardsCache = new HashMap<>(); view.setDelegate(this); } @Override public void onBackClicked() { final WizardPage prevPage = wizard.navigateToPrevious(); if (prevPage != null) { showPage(prevPage); } } @Override public void onNextClicked() { final WizardPage nextPage = wizard.navigateToNext(); if (nextPage != null) { showPage(nextPage); } } @Override public void onSaveClicked() { view.setLoaderVisibility(true); wizard.complete(new Wizard.CompleteCallback() { @Override public void onCompleted() { view.close(); } @Override public void onFailure(Throwable e) { dialogFactory.createMessageDialog("Error", e.getMessage(), null).show(); view.setLoaderVisibility(false); } }); } @Override public void onCancelClicked() { view.close(); } @Override public void updateControls() { view.setPreviousButtonEnabled(wizard.hasPrevious()); view.setNextButtonEnabled(wizard.hasNext() && currentPage.isCompleted()); view.setFinishButtonEnabled(wizard.canComplete()); } /** Open the project wizard for creating a new project. */ public void show() { show(Path.ROOT); } /** Open the project wizard with given mode. */ public void show(Path parent) { resetState(); this.wizardMode = CREATE; MutableProjectConfig config = new MutableProjectConfig(); config.setPath(parent.toString()); showDialog(config); } /** Open the project wizard for updating the given {@code project}. */ public void show(@NotNull MutableProjectConfig project) { resetState(); wizardMode = UPDATE; showDialog(project); } private void resetState() { wizardsCache.clear(); categoriesPage = categoriesPageProvider.get(); wizardMode = null; categoriesPage.setProjectTypeSelectionListener(this); categoriesPage.setProjectTemplateSelectionListener(this); importWizard = null; } private void showDialog(@Nullable MutableProjectConfig dataObject) { wizard = createDefaultWizard(dataObject, wizardMode); final WizardPage<MutableProjectConfig> firstPage = wizard.navigateToFirst(); if (firstPage != null) { showPage(firstPage); view.showDialog(wizardMode); } } @Override public void onProjectTypeSelected(ProjectTypeDto projectType) { final MutableProjectConfig prevData = wizard.getDataObject(); wizard = getWizardForProjectType(projectType, prevData); wizard.navigateToFirst(); final MutableProjectConfig newProject = wizard.getDataObject(); // some values should be shared between wizards for different project types newProject.setPath(prevData.getPath()); newProject.setName(prevData.getName()); newProject.setDescription(prevData.getDescription()); newProject.setMixins(prevData.getMixins()); if (wizardMode == UPDATE) { newProject.setAttributes(prevData.getAttributes()); } else { final MutableProjectConfig.MutableSourceStorage sourceStorage = prevData.getSource(); if (sourceStorage != null) { // some values should be cleared when user switch between categories sourceStorage.setLocation(""); sourceStorage.setType(""); sourceStorage.getParameters().clear(); } prevData.getProjects().clear(); final List<AttributeDto> attributes = projectType.getAttributes(); Map<String, List<String>> prevDataAttributes = prevData.getAttributes(); Map<String, List<String>> newAttributes = new HashMap<>(); for (AttributeDto attribute : attributes) { if (prevDataAttributes.containsKey(attribute.getName())) { newAttributes.put(attribute.getName(), prevDataAttributes.get(attribute.getName())); } } newProject.setAttributes(newAttributes); } // set dataObject's values from projectType newProject.setType(projectType.getId()); } @Override public void onProjectTemplateSelected(ProjectTemplateDescriptor projectTemplate) { final MutableProjectConfig dataObject = wizard.getDataObject(); wizard = importWizard == null ? importWizard = createDefaultWizard(dataObject, IMPORT) : importWizard; wizard.navigateToFirst(); // set dataObject's values from projectTemplate final NewProjectConfig newProjectConfig = new NewProjectConfigImpl(projectTemplate); dataObject.setType(newProjectConfig.getType()); dataObject.setSource(newProjectConfig.getSource()); dataObject.setAttributes(newProjectConfig.getAttributes()); dataObject.setOptions(newProjectConfig.getOptions()); dataObject.setCommands(projectTemplate.getCommands()); } /** Creates or returns project wizard for the specified projectType with the given dataObject. */ private ProjectWizard getWizardForProjectType(@NotNull ProjectTypeDto projectType, @NotNull MutableProjectConfig configDto) { if (wizardsCache.containsKey(projectType)) { return wizardsCache.get(projectType); } final ProjectWizardRegistrar wizardRegistrar = wizardRegistry.getWizardRegistrar(projectType.getId()); if (wizardRegistrar == null) { // should never occur throw new IllegalStateException("WizardRegistrar for the project type " + projectType.getId() + " isn't registered."); } List<Provider<? extends WizardPage<MutableProjectConfig>>> pageProviders = wizardRegistrar.getWizardPages(); final ProjectWizard projectWizard = createDefaultWizard(configDto, wizardMode); for (Provider<? extends WizardPage<MutableProjectConfig>> provider : pageProviders) { projectWizard.addPage(provider.get(), 1, false); } wizardsCache.put(projectType, projectWizard); return projectWizard; } /** Creates and returns 'default' project wizard with pre-defined pages only. */ private ProjectWizard createDefaultWizard(@Nullable MutableProjectConfig dataObject, @NotNull ProjectWizardMode mode) { final ProjectWizard projectWizard = projectWizardFactory.newWizard(dataObject, mode); projectWizard.setUpdateDelegate(this); // add pre-defined pages - first and last projectWizard.addPage(categoriesPage); return projectWizard; } private void showPage(@NotNull WizardPage wizardPage) { currentPage = wizardPage; updateControls(); view.showPage(currentPage); } }