/******************************************************************************* * 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.ext.git.client.importer.page; import com.google.common.base.Strings; import com.google.gwt.regexp.shared.RegExp; import com.google.gwt.user.client.ui.AcceptsOneWidget; import com.google.inject.Inject; import org.eclipse.che.ide.api.project.MutableProjectConfig; import org.eclipse.che.ide.api.wizard.AbstractWizardPage; import org.eclipse.che.ide.ext.git.client.GitLocalizationConstant; import org.eclipse.che.ide.util.NameUtils; import javax.validation.constraints.NotNull; import java.util.HashMap; import java.util.Map; /** * @author Roman Nikitenko */ public class GitImporterPagePresenter extends AbstractWizardPage<MutableProjectConfig> implements GitImporterPageView.ActionDelegate { // An alternative scp-like syntax: [user@]host.xz:path/to/repo.git/ private static final RegExp SCP_LIKE_SYNTAX = RegExp.compile("([A-Za-z0-9_\\-]+\\.[A-Za-z0-9_\\-:]+)+:"); // the transport protocol private static final RegExp PROTOCOL = RegExp.compile("((http|https|git|ssh|ftp|ftps)://)"); // the address of the remote server between // and / private static final RegExp HOST1 = RegExp.compile("//([A-Za-z0-9_\\-]+\\.[A-Za-z0-9_\\-:]+)+/"); // the address of the remote server between @ and : or / private static final RegExp HOST2 = RegExp.compile("@([A-Za-z0-9_\\-]+\\.[A-Za-z0-9_\\-:]+)+[:/]"); // the repository name private static final RegExp REPO_NAME = RegExp.compile("/[A-Za-z0-9_.\\-]+$"); // start with white space private static final RegExp WHITE_SPACE = RegExp.compile("^\\s"); private GitLocalizationConstant locale; private GitImporterPageView view; private boolean ignoreChanges; @Inject public GitImporterPagePresenter(GitImporterPageView view, GitLocalizationConstant locale) { this.view = view; this.view.setDelegate(this); this.locale = locale; } @Override public boolean isCompleted() { return isGitUrlCorrect(dataObject.getSource().getLocation()); } @Override public void projectNameChanged(@NotNull String name) { if (ignoreChanges) { return; } dataObject.setName(name); updateDelegate.updateControls(); validateProjectName(); } private void validateProjectName() { if (NameUtils.checkProjectName(view.getProjectName())) { view.markNameValid(); } else { view.markNameInvalid(); } } @Override public void projectUrlChanged(@NotNull String url) { if (ignoreChanges) { return; } dataObject.getSource().setLocation(url); isGitUrlCorrect(url); String projectName = view.getProjectName(); if (projectName.isEmpty()) { projectName = extractProjectNameFromUri(url); dataObject.setName(projectName); view.setProjectName(projectName); validateProjectName(); } updateDelegate.updateControls(); } @Override public void onRecursiveSelected(boolean recursiveSelected) { if (recursiveSelected) { projectParameters().put("recursive", null); } else { projectParameters().remove("recursive"); } } @Override public void projectDescriptionChanged(@NotNull String projectDescription) { dataObject.setDescription(projectDescription); updateDelegate.updateControls(); } /** * Returns project parameters map. * * @return parameters map */ private Map<String, String> projectParameters() { Map<String, String> parameters = dataObject.getSource().getParameters(); if (parameters == null) { parameters = new HashMap<>(); dataObject.getSource().setParameters(parameters); } return parameters; } @Override public void keepDirectorySelected(boolean keepDirectory) { view.enableDirectoryNameField(keepDirectory); if (keepDirectory) { projectParameters().put("keepDir", view.getDirectoryName()); dataObject.setType("blank"); view.highlightDirectoryNameField(!NameUtils.checkProjectName(view.getDirectoryName())); view.focusDirectoryNameField(); } else { projectParameters().remove("keepDir"); dataObject.setType(null); view.highlightDirectoryNameField(false); } } @Override public void keepDirectoryNameChanged(@NotNull String directoryName) { if (view.keepDirectory()) { projectParameters().put("keepDir", directoryName); dataObject.setType("blank"); view.highlightDirectoryNameField(!NameUtils.checkProjectName(view.getDirectoryName())); } else { projectParameters().remove("keepDir"); dataObject.setType(null); view.highlightDirectoryNameField(false); } } @Override public void branchSelected(boolean branch) { view.enableBranchNameField(branch); if (view.isBranchName()) { projectParameters().put("branch", view.getBranchName()); view.focusBranchNameField(); } else { projectParameters().remove("branch"); } } @Override public void branchNameChanged(@NotNull String branch) { if (view.isBranchName()) { projectParameters().put("branch", branch); } else { projectParameters().remove("branch"); } } @Override public void go(@NotNull AcceptsOneWidget container) { container.setWidget(view); if (Strings.isNullOrEmpty(dataObject.getName()) && Strings.isNullOrEmpty(dataObject.getSource().getLocation())) { ignoreChanges = true; view.unmarkURL(); view.unmarkName(); view.setURLErrorMessage(null); } view.setProjectName(dataObject.getName()); view.setProjectDescription(dataObject.getDescription()); view.setProjectUrl(dataObject.getSource().getLocation()); view.setKeepDirectoryChecked(false); view.setBranchChecked(false); view.setDirectoryName(""); view.setBranchName(""); view.enableDirectoryNameField(false); view.enableBranchNameField(false); view.highlightDirectoryNameField(false); view.setInputsEnableState(true); view.focusInUrlInput(); ignoreChanges = false; } /** Gets project name from uri. */ private String extractProjectNameFromUri(@NotNull String uri) { int indexFinishProjectName = uri.lastIndexOf("."); int indexStartProjectName = uri.lastIndexOf("/") != -1 ? uri.lastIndexOf("/") + 1 : (uri.lastIndexOf(":") + 1); if (indexStartProjectName != 0 && indexStartProjectName < indexFinishProjectName) { return uri.substring(indexStartProjectName, indexFinishProjectName); } if (indexStartProjectName != 0) { return uri.substring(indexStartProjectName); } return ""; } /** * Validate url * * @param url * url for validate * @return <code>true</code> if url is correct */ private boolean isGitUrlCorrect(@NotNull String url) { if (WHITE_SPACE.test(url)) { view.markURLInvalid(); view.setURLErrorMessage(locale.importProjectMessageStartWithWhiteSpace()); return false; } if (SCP_LIKE_SYNTAX.test(url)) { view.markURLValid(); view.setURLErrorMessage(null); return true; } if (!PROTOCOL.test(url)) { view.markURLInvalid(); view.setURLErrorMessage(locale.importProjectMessageProtocolIncorrect()); return false; } if (!(HOST1.test(url) || HOST2.test(url))) { view.markURLInvalid(); view.setURLErrorMessage(locale.importProjectMessageHostIncorrect()); return false; } if (!(REPO_NAME.test(url))) { view.markURLInvalid(); view.setURLErrorMessage(locale.importProjectMessageNameRepoIncorrect()); return false; } view.markURLValid(); view.setURLErrorMessage(null); return true; } }