package org.abapgit.adt.ui.internal.wizards; import java.lang.reflect.InvocationTargetException; import java.util.LinkedList; import java.util.List; import org.abapgit.adt.backend.IApackManifest; import org.abapgit.adt.backend.IApackManifest.IApackDependency; import org.abapgit.adt.backend.IRepositoryService; import org.abapgit.adt.backend.RepositoryServiceFactory; import org.abapgit.adt.backend.model.abapObjects.IAbapObject; import org.abapgit.adt.backend.model.abapgitexternalrepo.IExternalRepositoryInfo; import org.abapgit.adt.backend.model.abapgitrepositories.IRepositories; import org.abapgit.adt.backend.model.abapgitrepositories.IRepository; import org.abapgit.adt.backend.model.abapgitrepositories.impl.AbapgitrepositoriesFactoryImpl; import org.abapgit.adt.ui.AbapGitUIPlugin; import org.abapgit.adt.ui.internal.i18n.Messages; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.dialogs.DialogPage; import org.eclipse.jface.dialogs.IPageChangingListener; import org.eclipse.jface.dialogs.PageChangingEvent; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.wizard.IWizardContainer; import org.eclipse.jface.wizard.IWizardPage; import org.eclipse.jface.wizard.Wizard; import org.eclipse.jface.wizard.WizardDialog; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.ui.plugin.AbstractUIPlugin; import com.sap.adt.tools.core.model.adtcore.IAdtCoreFactory; import com.sap.adt.tools.core.model.adtcore.IAdtObjectReference; import com.sap.adt.tools.core.project.AdtProjectServiceFactory; import com.sap.adt.transport.AdtTransportServiceFactory; import com.sap.adt.transport.IAdtTransportCheckData; import com.sap.adt.transport.IAdtTransportService; import com.sap.adt.transport.ui.wizard.AdtTransportSelectionWizardPageFactory; import com.sap.adt.transport.ui.wizard.IAdtTransportSelectionWizardPage; public class AbapGitWizard extends Wizard { private final IProject project; private final String destination; private final CloneData cloneData; private PageChangeListener pageChangeListener; private AbapGitWizardPageRepositoryAndCredentials pageRepo; private AbapGitWizardPageBranchAndPackage pageBranchAndPackage; private AbapGitWizardPageApack pageApack; private IAdtTransportService transportService; private IAdtTransportSelectionWizardPage transportPage; public AbapGitWizard(IProject project) { this.project = project; this.destination = AdtProjectServiceFactory.createProjectService().getDestinationId(project); this.cloneData = new CloneData(); setWindowTitle(Messages.AbapGitWizard_title); setNeedsProgressMonitor(true); setDefaultPageImageDescriptor( AbstractUIPlugin.imageDescriptorFromPlugin(AbapGitUIPlugin.PLUGIN_ID, "icons/wizban/abapGit_import_wizban.png")); //$NON-NLS-1$ } @Override public void addPages() { this.pageRepo = new AbapGitWizardPageRepositoryAndCredentials(this.project, this.destination, this.cloneData, false); this.pageBranchAndPackage = new AbapGitWizardPageBranchAndPackage(this.project, this.destination, this.cloneData, false); this.transportService = AdtTransportServiceFactory.createTransportService(this.destination); this.pageApack = new AbapGitWizardPageApack(this.destination, this.cloneData, this.transportService, false); this.transportPage = AdtTransportSelectionWizardPageFactory.createTransportSelectionPage(this.transportService); addPage(this.pageRepo); addPage(this.pageBranchAndPackage); addPage(this.pageApack); addPage(this.transportPage); } @Override public boolean performFinish() { //validate input if pageBranchAndPackage finished early if (getContainer().getCurrentPage() == this.pageBranchAndPackage && !this.pageBranchAndPackage.validateAll()) { return false; } //validate input if pageApack finished early if (getContainer().getCurrentPage() == this.pageApack && !this.pageApack.validateAll()) { return false; } List<IAbapObject> cloneObjects = new LinkedList<>(); try { String transportRequestNumber = this.transportPage.getTransportRequestNumber(); getContainer().run(true, true, new IRunnableWithProgress() { @Override public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { Boolean sequenceLnp = AbapGitWizard.this.pageBranchAndPackage.getLnpSequence(); monitor.beginTask(Messages.AbapGitWizard_task_cloning_repository, IProgressMonitor.UNKNOWN); IRepositoryService repoService = RepositoryServiceFactory.createRepositoryService(AbapGitWizard.this.destination, monitor); if (AbapGitWizard.this.cloneData.hasDependencies()) { IRepositories repositoriesToLink = AbapgitrepositoriesFactoryImpl.eINSTANCE.createRepositories(); repositoriesToLink.getRepositories() .add(createRepository(AbapGitWizard.this.cloneData.url, AbapGitWizard.this.cloneData.branch, AbapGitWizard.this.cloneData.packageRef.getName(), transportRequestNumber, AbapGitWizard.this.cloneData.user, AbapGitWizard.this.cloneData.pass)); for (IApackDependency apackDependency : AbapGitWizard.this.cloneData.apackManifest.getDescriptor() .getDependencies()) { if (apackDependency.requiresSynchronization()) { repositoriesToLink.getRepositories() .add(createRepository(apackDependency.getGitUrl(), IApackManifest.MASTER_BRANCH, apackDependency.getTargetPackage().getName(), transportRequestNumber, AbapGitWizard.this.cloneData.user, AbapGitWizard.this.cloneData.pass)); } } repoService.cloneRepositories(repositoriesToLink, monitor); if (sequenceLnp) { pullLinkedRepositories(monitor, repoService, repositoriesToLink); } } else { List<IAbapObject> abapObjects = repoService.cloneRepository(AbapGitWizard.this.cloneData.url, AbapGitWizard.this.cloneData.branch, AbapGitWizard.this.cloneData.packageRef.getName(), transportRequestNumber, AbapGitWizard.this.cloneData.user, AbapGitWizard.this.cloneData.pass, monitor) .getAbapObjects(); cloneObjects.addAll(abapObjects); //-> Check if link and pull sequence is set if (sequenceLnp) { //-> Get linked repository by url IRepository linkedRepo = repoService.getRepositoryByURL(repoService.getRepositories(monitor), AbapGitWizard.this.cloneData.url); //-> Pull newly linked repository repoService.pullRepository(linkedRepo, AbapGitWizard.this.cloneData.branch, AbapGitWizard.this.transportPage.getTransportRequestNumber(), AbapGitWizard.this.cloneData.user, AbapGitWizard.this.cloneData.pass, monitor); } } } private void pullLinkedRepositories(IProgressMonitor monitor, IRepositoryService repoService, IRepositories repositoriesToLink) { // Need to retrieve linked repositories as only they contain the PULL link needed to continue... IRepositories linkedRepositories = repoService.getRepositories(monitor); for (IRepository repository : repositoriesToLink.getRepositories()) { IRepository linkedRepository = repoService.getRepositoryByURL(linkedRepositories, repository.getUrl()); if (linkedRepository != null) { repoService.pullRepository(linkedRepository, linkedRepository.getBranchName(), AbapGitWizard.this.transportPage.getTransportRequestNumber(), AbapGitWizard.this.cloneData.user, AbapGitWizard.this.cloneData.pass, monitor); } } } }); return true; } catch (InterruptedException e) { return false; } catch (InvocationTargetException e) { ((WizardPage) getContainer().getCurrentPage()).setPageComplete(false); ((WizardPage) getContainer().getCurrentPage()).setMessage(e.getTargetException().getMessage(), DialogPage.ERROR); return false; } } @Override public void setContainer(IWizardContainer wizardContainer) { super.setContainer(wizardContainer); if (this.pageChangeListener == null && wizardContainer != null) { Assert.isLegal(wizardContainer instanceof WizardDialog, "Wizard container must be of type WizardDialog"); //$NON-NLS-1$ this.pageChangeListener = new PageChangeListener(); ((WizardDialog) wizardContainer).addPageChangingListener(this.pageChangeListener); } } private final class PageChangeListener implements IPageChangingListener { @Override public void handlePageChanging(final PageChangingEvent event) { //-> Credentials page -> Branch & Package page if (event.getCurrentPage() == AbapGitWizard.this.pageRepo && event.getTargetPage() == AbapGitWizard.this.pageBranchAndPackage && !AbapGitWizard.this.pageRepo.validateAll()) { event.doit = false; return; } //-> Branch & Package page -> Credentials page if (event.getCurrentPage() == AbapGitWizard.this.pageBranchAndPackage && event.getTargetPage() == AbapGitWizard.this.pageRepo) { event.doit = true; return; } //-> Branch & Package page -> Transport page if (event.getCurrentPage() == AbapGitWizard.this.pageBranchAndPackage && event.getTargetPage() == AbapGitWizard.this.transportPage) { if (!AbapGitWizard.this.pageBranchAndPackage.validateAll()) { event.doit = false; return; } } //-> Branch & Package page -> Any page if (event.getCurrentPage() == AbapGitWizard.this.pageBranchAndPackage && !AbapGitWizard.this.pageBranchAndPackage.validateAll()) { event.doit = false; return; } //-> Prepare transport page if (event.getTargetPage() == AbapGitWizard.this.transportPage) { try { // The transport service requires URIs to objects we want to create in the // target package. // However, we do not know these URIs from the client. // Instead, give it the URI of the package in which we clone. IAdtObjectReference packageRef = AbapGitWizard.this.cloneData.packageRef; IAdtObjectReference checkRef = IAdtCoreFactory.eINSTANCE.createAdtObjectReference(); checkRef.setUri(packageRef.getUri()); IAdtTransportCheckData checkData = AbapGitWizard.this.transportService.check(checkRef, packageRef.getPackageName(), true); AbapGitWizard.this.transportPage.setCheckData(checkData); } catch (Exception e) { AbapGitWizard.this.pageBranchAndPackage.setMessage(e.getMessage(), DialogPage.ERROR); } } //-> APACK page -> Any page if (event.getCurrentPage() == AbapGitWizard.this.pageApack && !AbapGitWizard.this.pageApack.validateAll()) { event.doit = false; return; } } } @Override public IWizardPage getNextPage(IWizardPage page) { if (page.equals(this.pageBranchAndPackage) && !this.cloneData.hasDependencies()) { // If we don't have APACK dependencies, we can skip the APACK-related page return this.transportPage; } else { return super.getNextPage(page); } } @Override public boolean canFinish() { if (getContainer().getCurrentPage() == this.pageBranchAndPackage && this.pageBranchAndPackage.canFinishEarly()) { return true; } if (getContainer().getCurrentPage() == this.pageApack && this.pageApack.canFinishEarly()) { return true; } return super.canFinish(); } //If a pull is to be done after link. public boolean linkAndPull() { return this.pageBranchAndPackage.getLnpSequence(); } private IRepository createRepository(String url, String branch, String targetPackage, String transportRequest, String userName, String password) { IRepository repository = AbapgitrepositoriesFactoryImpl.eINSTANCE.createRepository(); repository.setUrl(url); repository.setBranchName(branch); repository.setPackage(targetPackage); repository.setTransportRequest(transportRequest); repository.setRemoteUser(userName); repository.setRemotePassword(password); return repository; } /** * Simple data exchange object for the wizard and its pages. This might be * refined in the future, e.g. by using data binding. */ static class CloneData { public IRepositories repositories; public IExternalRepositoryInfo externalRepoInfo; public IAdtObjectReference packageRef; public String branch; public String url; public String user; public String pass; public IApackManifest apackManifest; public boolean hasDependencies() { return this.apackManifest != null && this.apackManifest.hasDependencies(); } } }