RTSDK : Resolved illegal access problems while using EGit plug-in
authordaeryong.park <bdragon.park@samsung.com>
Tue, 7 Mar 2017 08:32:22 +0000 (17:32 +0900)
committerdaeryong.park <bdragon.park@samsung.com>
Tue, 7 Mar 2017 08:32:22 +0000 (17:32 +0900)
- Resolved illegal access problems while using EGit plug-in (Create
project from git)

Change-Id: Ie6fb16565fbfd1281f497ee0f8241281a3611329
Signed-off-by: daeryong.park <bdragon.park@samsung.com>
rt-ide/tizen.rt.product.plugin/src/org/eclipse/egit/ui/internal/clone/AbstractRtGitCloneWizard.java [new file with mode: 0644]
rt-ide/tizen.rt.product.plugin/src/org/eclipse/egit/ui/internal/clone/RtCloneDestinationPage.java [new file with mode: 0644]
rt-ide/tizen.rt.product.plugin/src/org/eclipse/egit/ui/internal/clone/RtGitImportWizard.java
rt-ide/tizen.rt.product.plugin/src/org/eclipse/egit/ui/internal/clone/RtSourceBranchPage.java [new file with mode: 0644]

diff --git a/rt-ide/tizen.rt.product.plugin/src/org/eclipse/egit/ui/internal/clone/AbstractRtGitCloneWizard.java b/rt-ide/tizen.rt.product.plugin/src/org/eclipse/egit/ui/internal/clone/AbstractRtGitCloneWizard.java
new file mode 100644 (file)
index 0000000..828df2a
--- /dev/null
@@ -0,0 +1,464 @@
+/*******************************************************************************\r
+ * Copyright (C) 2008, Roger C. Soares <rogersoares@intelinet.com.br>\r
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>\r
+ * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>\r
+ * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>\r
+ * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>\r
+ * Copyright (C) 2010, Benjamin Muskalla <bmuskalla@eclipsesource.com>\r
+ * Copyright (C) 2012, Stefan Lay <stefan.lay@sap.com>\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *******************************************************************************/\r
+\r
+package org.eclipse.egit.ui.internal.clone;\r
+\r
+import java.io.File;\r
+import java.lang.reflect.InvocationTargetException;\r
+import java.net.URISyntaxException;\r
+import java.text.MessageFormat;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.LinkedHashSet;\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+import org.eclipse.core.resources.WorkspaceJob;\r
+import org.eclipse.core.runtime.CoreException;\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.IStatus;\r
+import org.eclipse.core.runtime.Status;\r
+import org.eclipse.core.runtime.jobs.Job;\r
+import org.eclipse.egit.core.RepositoryUtil;\r
+import org.eclipse.egit.core.internal.util.ProjectUtil;\r
+import org.eclipse.egit.core.op.CloneOperation;\r
+import org.eclipse.egit.core.op.CloneOperation.PostCloneTask;\r
+import org.eclipse.egit.core.op.ConfigureFetchAfterCloneTask;\r
+import org.eclipse.egit.core.op.ConfigureGerritAfterCloneTask;\r
+import org.eclipse.egit.core.op.ConfigurePushAfterCloneTask;\r
+import org.eclipse.egit.core.op.SetRepositoryConfigPropertyTask;\r
+import org.eclipse.egit.core.securestorage.UserPasswordCredentials;\r
+import org.eclipse.egit.ui.Activator;\r
+import org.eclipse.egit.ui.JobFamilies;\r
+import org.eclipse.egit.ui.UIPreferences;\r
+import org.eclipse.egit.ui.internal.SecureStoreUtils;\r
+import org.eclipse.egit.ui.internal.UIText;\r
+import org.eclipse.egit.ui.internal.clone.GitCloneSourceProviderExtension.CloneSourceProvider;\r
+import org.eclipse.egit.ui.internal.components.RepositorySelection;\r
+import org.eclipse.egit.ui.internal.credentials.EGitCredentialsProvider;\r
+import org.eclipse.egit.ui.internal.provisional.wizards.GitRepositoryInfo;\r
+import org.eclipse.egit.ui.internal.provisional.wizards.GitRepositoryInfo.PushInfo;\r
+import org.eclipse.egit.ui.internal.provisional.wizards.GitRepositoryInfo.RepositoryConfigProperty;\r
+import org.eclipse.egit.ui.internal.provisional.wizards.IRepositorySearchResult;\r
+import org.eclipse.egit.ui.internal.provisional.wizards.NoRepositoryInfoException;\r
+import org.eclipse.jface.dialogs.ErrorDialog;\r
+import org.eclipse.jface.operation.IRunnableWithProgress;\r
+import org.eclipse.jface.wizard.IWizardContainer;\r
+import org.eclipse.jface.wizard.IWizardPage;\r
+import org.eclipse.jface.wizard.Wizard;\r
+import org.eclipse.jface.wizard.WizardPage;\r
+import org.eclipse.jgit.lib.Ref;\r
+import org.eclipse.jgit.lib.Repository;\r
+import org.eclipse.jgit.transport.CredentialsProvider;\r
+import org.eclipse.jgit.transport.URIish;\r
+import org.eclipse.osgi.util.NLS;\r
+import org.eclipse.ui.IWorkingSet;\r
+\r
+/**\r
+ * Implements the basic functionality of a clone wizard\r
+ */\r
+public abstract class AbstractRtGitCloneWizard extends Wizard {\r
+\r
+    /**\r
+     * a page for branch selection\r
+     */\r
+    protected RtSourceBranchPage validSource;\r
+\r
+    /**\r
+     * a page for selection of the clone destination\r
+     */\r
+    protected RtCloneDestinationPage cloneDestination;\r
+\r
+    /**\r
+     * the path where a clone has been created in\r
+     */\r
+    protected String alreadyClonedInto;\r
+\r
+    /**\r
+     * whether the clone operation is done later on by the caller of the wizard\r
+     */\r
+    protected boolean callerRunsCloneOperation;\r
+\r
+    /**\r
+     * the result which was found when the last search was done\r
+     */\r
+    protected IRepositorySearchResult currentSearchResult;\r
+\r
+    private CloneOperation cloneOperation;\r
+\r
+    /**\r
+     * Construct the clone wizard based on given repository search result. If the search result is an instance of org.eclipse.jface.wizard.WizardPage, then the page is shown in the wizard before the\r
+     * repository info is read. The repository location page that allows the repository info to be provided by different search providers is not shown.\r
+     * @param searchResult the search result to initialize the clone wizard with.\r
+     */\r
+    public AbstractRtGitCloneWizard(IRepositorySearchResult searchResult) {\r
+        this();\r
+        this.currentSearchResult = searchResult;\r
+    }\r
+\r
+    /**\r
+     * Construct the clone wizard with a repository location page that allows the repository info to be provided by different search providers.\r
+     */\r
+    public AbstractRtGitCloneWizard() {\r
+        setNeedsProgressMonitor(true);\r
+        validSource = new RtSourceBranchPage() {\r
+\r
+            @Override\r
+            public void setVisible(boolean visible) {\r
+                if (visible) {\r
+                    setSelection(getRepositorySelection());\r
+                    setCredentials(getCredentials());\r
+                }\r
+                super.setVisible(visible);\r
+            }\r
+        };\r
+        cloneDestination = new RtCloneDestinationPage() {\r
+            @Override\r
+            public void setVisible(boolean visible) {\r
+                if (visible)\r
+                    setSelection(getRepositorySelection(),\r
+                            validSource.getAvailableBranches(),\r
+                            validSource.getSelectedBranches(),\r
+                            validSource.getHEAD());\r
+                super.setVisible(visible);\r
+            }\r
+        };\r
+    }\r
+\r
+    /**\r
+     * subclasses may add pages to the Wizard which will be shown before the clone step\r
+     */\r
+    protected abstract void addPreClonePages();\r
+\r
+    /**\r
+     * subclasses may add pages to the Wizard which will be shown after the clone step\r
+     */\r
+    protected abstract void addPostClonePages();\r
+\r
+    @Override\r
+    final public void addPages() {\r
+        if (hasSearchResult())\r
+            addRepositorySearchPage();\r
+        else\r
+            addRepositoryLocationPage();\r
+        addPreClonePages();\r
+        addPage(validSource);\r
+        addPage(cloneDestination);\r
+        addPostClonePages();\r
+    }\r
+\r
+    /**\r
+     * @return if the search result is set\r
+     */\r
+    protected boolean hasSearchResult() {\r
+        return currentSearchResult != null;\r
+    }\r
+\r
+    private void addRepositorySearchPage() {\r
+        if (currentSearchResult instanceof WizardPage)\r
+            addPage((WizardPage) currentSearchResult);\r
+    }\r
+\r
+    private void addRepositoryLocationPage() {\r
+        List<CloneSourceProvider> cloneSourceProviders = getCloneSourceProviders();\r
+        if (hasSingleCloneSourceProviderWithFixedLocation(cloneSourceProviders))\r
+            try {\r
+                addPage(cloneSourceProviders.get(0).getRepositorySearchPage());\r
+            } catch (CoreException e) {\r
+                Activator.logError(e.getLocalizedMessage(), e);\r
+            }\r
+        else\r
+            addPage(new RepositoryLocationPage(cloneSourceProviders));\r
+    }\r
+\r
+    private boolean hasSingleCloneSourceProviderWithFixedLocation(\r
+            List<CloneSourceProvider> cloneSourceProviders) {\r
+        return cloneSourceProviders.size() == 1 && cloneSourceProviders.get(0).hasFixLocation();\r
+    }\r
+\r
+    /**\r
+     * @return a list of CloneSourceProviders, may be extended by a subclass\r
+     */\r
+    protected List<CloneSourceProvider> getCloneSourceProviders() {\r
+        return GitCloneSourceProviderExtension.getCloneSourceProvider();\r
+    }\r
+\r
+    /**\r
+     * Do the clone using data which were collected on the pages {@code validSource} and {@code cloneDestination}\r
+     * @param gitRepositoryInfo\r
+     * @return if clone was successful\r
+     * @throws URISyntaxException\r
+     */\r
+    protected boolean performClone(GitRepositoryInfo gitRepositoryInfo) throws URISyntaxException {\r
+        URIish uri = new URIish(gitRepositoryInfo.getCloneUri());\r
+        UserPasswordCredentials credentials = gitRepositoryInfo.getCredentials();\r
+        setWindowTitle(NLS.bind(UIText.GitCloneWizard_jobName, uri.toString()));\r
+        final boolean allSelected;\r
+        final Collection<Ref> selectedBranches;\r
+        if (validSource.isSourceRepoEmpty()) {\r
+            // fetch all branches of empty repo\r
+            allSelected = true;\r
+            selectedBranches = Collections.emptyList();\r
+        } else {\r
+            allSelected = validSource.isAllSelected();\r
+            selectedBranches = validSource.getSelectedBranches();\r
+        }\r
+        final File workdir = cloneDestination.getDestinationFile();\r
+        final Ref ref = cloneDestination.getInitialBranch();\r
+        final String remoteName = cloneDestination.getRemote();\r
+\r
+        boolean created = workdir.exists();\r
+        if (!created)\r
+            created = workdir.mkdirs();\r
+\r
+        if (!created || !workdir.isDirectory()) {\r
+            final String errorMessage = NLS.bind(\r
+                    UIText.GitCloneWizard_errorCannotCreate, workdir.getPath());\r
+            ErrorDialog.openError(getShell(), getWindowTitle(),\r
+                    UIText.GitCloneWizard_failed, new Status(IStatus.ERROR,\r
+                            Activator.getPluginId(), 0, errorMessage, null));\r
+            // let's give user a chance to fix this minor problem\r
+            return false;\r
+        }\r
+\r
+        int timeout = Activator.getDefault().getPreferenceStore()\r
+                .getInt(UIPreferences.REMOTE_CONNECTION_TIMEOUT);\r
+        final CloneOperation op = new CloneOperation(uri, allSelected,\r
+                selectedBranches, workdir, ref != null ? ref.getName() : null,\r
+                remoteName, timeout);\r
+        CredentialsProvider credentialsProvider = null;\r
+        if (credentials != null) {\r
+            credentialsProvider = new EGitCredentialsProvider(\r
+                    credentials.getUser(), credentials.getPassword());\r
+        } else {\r
+            credentialsProvider = new EGitCredentialsProvider();\r
+        }\r
+        op.setCredentialsProvider(credentialsProvider);\r
+        op.setCloneSubmodules(cloneDestination.isCloneSubmodules());\r
+\r
+        configureFetchSpec(op, gitRepositoryInfo, remoteName);\r
+        configurePush(op, gitRepositoryInfo, remoteName);\r
+        configureRepositoryConfig(op, gitRepositoryInfo);\r
+        configureGerrit(op, gitRepositoryInfo, credentialsProvider, remoteName,\r
+                timeout);\r
+\r
+        if (cloneDestination.isImportProjects()) {\r
+            final IWorkingSet[] sets = cloneDestination.getWorkingSets();\r
+            op.addPostCloneTask(new PostCloneTask() {\r
+                @Override\r
+                public void execute(Repository repository,\r
+                        IProgressMonitor monitor) throws CoreException {\r
+                    importProjects(repository, sets);\r
+                }\r
+            });\r
+        }\r
+\r
+        alreadyClonedInto = workdir.getPath();\r
+\r
+        if (!callerRunsCloneOperation)\r
+            runAsJob(uri, op, gitRepositoryInfo);\r
+        else\r
+            cloneOperation = op;\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public IWizardPage getNextPage(IWizardPage page) {\r
+        if (page instanceof IRepositorySearchResult) {\r
+            currentSearchResult = (IRepositorySearchResult) page;\r
+            return validSource;\r
+        }\r
+        return super.getNextPage(page);\r
+    }\r
+\r
+    /**\r
+     * @return the repository selected by the user\r
+     */\r
+    protected RepositorySelection getRepositorySelection() {\r
+        try {\r
+            return (new RepositorySelection(new URIish(currentSearchResult.getGitRepositoryInfo().getCloneUri()), null));\r
+        } catch (URISyntaxException e) {\r
+            Activator.error(UIText.GitImportWizard_errorParsingURI, e);\r
+            return null;\r
+        } catch (NoRepositoryInfoException e) {\r
+            Activator.error(UIText.GitImportWizard_noRepositoryInfo, e);\r
+            return null;\r
+        } catch (Exception e) {\r
+            Activator.error(e.getMessage(), e);\r
+            return null;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * @return the credentials\r
+     */\r
+    protected UserPasswordCredentials getCredentials() {\r
+        try {\r
+            return currentSearchResult.getGitRepositoryInfo().getCredentials();\r
+        } catch (NoRepositoryInfoException e) {\r
+            Activator.error(UIText.GitImportWizard_noRepositoryInfo, e);\r
+            return null;\r
+        } catch (Exception e) {\r
+            Activator.error(e.getMessage(), e);\r
+            return null;\r
+        }\r
+    }\r
+\r
+    private void configureFetchSpec(CloneOperation op,\r
+            GitRepositoryInfo gitRepositoryInfo, String remoteName) {\r
+        for (String fetchRefSpec : gitRepositoryInfo.getFetchRefSpecs())\r
+            op.addPostCloneTask(new ConfigureFetchAfterCloneTask(remoteName, fetchRefSpec));\r
+    }\r
+\r
+    private void configurePush(CloneOperation op,\r
+            GitRepositoryInfo gitRepositoryInfo, String remoteName) {\r
+        for (PushInfo pushInfo : gitRepositoryInfo.getPushInfos())\r
+            try {\r
+                URIish uri = pushInfo.getPushUri() != null ? new URIish(\r
+                        pushInfo.getPushUri()) : null;\r
+                ConfigurePushAfterCloneTask task = new ConfigurePushAfterCloneTask(\r
+                        remoteName, pushInfo.getPushRefSpec(), uri);\r
+                op.addPostCloneTask(task);\r
+            } catch (URISyntaxException e) {\r
+                Activator.handleError(UIText.GitCloneWizard_failed, e, true);\r
+            }\r
+    }\r
+\r
+    private void configureRepositoryConfig(CloneOperation op, GitRepositoryInfo gitRepositoryInfo) {\r
+        for (RepositoryConfigProperty p : gitRepositoryInfo.getRepositoryConfigProperties()) {\r
+            SetRepositoryConfigPropertyTask task = new SetRepositoryConfigPropertyTask(\r
+                    p.getSection(), p.getSubsection(), p.getName(),\r
+                    p.getValue());\r
+            op.addPostCloneTask(task);\r
+        }\r
+    }\r
+\r
+    private void configureGerrit(CloneOperation op,\r
+            GitRepositoryInfo gitRepositoryInfo,\r
+            CredentialsProvider credentialsProvider, String remoteName,\r
+            int timeout) {\r
+        ConfigureGerritAfterCloneTask task = new ConfigureGerritAfterCloneTask(\r
+                gitRepositoryInfo.getCloneUri(), remoteName,\r
+                credentialsProvider, timeout);\r
+        op.addPostCloneTask(task);\r
+    }\r
+\r
+    private void importProjects(final Repository repository,\r
+            final IWorkingSet[] sets) {\r
+        String repoName = Activator.getDefault().getRepositoryUtil()\r
+                .getRepositoryName(repository);\r
+        Job importJob = new WorkspaceJob(MessageFormat.format(\r
+                UIText.GitCloneWizard_jobImportProjects, repoName)) {\r
+\r
+            @Override\r
+            public IStatus runInWorkspace(IProgressMonitor monitor) {\r
+                List<File> files = new ArrayList<File>();\r
+                ProjectUtil.findProjectFiles(files, repository.getWorkTree(),\r
+                        true, monitor);\r
+                if (files.isEmpty())\r
+                    return Status.OK_STATUS;\r
+\r
+                Set<ProjectRecord> records = new LinkedHashSet<ProjectRecord>();\r
+                for (File file : files)\r
+                    records.add(new ProjectRecord(file));\r
+                try {\r
+                    ProjectUtils.createProjects(records, sets, monitor);\r
+                } catch (InvocationTargetException e) {\r
+                    Activator.logError(e.getLocalizedMessage(), e);\r
+                } catch (InterruptedException e) {\r
+                    Activator.logError(e.getLocalizedMessage(), e);\r
+                }\r
+                return Status.OK_STATUS;\r
+            }\r
+        };\r
+        importJob.schedule();\r
+    }\r
+\r
+    /**\r
+     * @param container\r
+     * @param repositoryInfo\r
+     */\r
+    public void runCloneOperation(IWizardContainer container, final GitRepositoryInfo repositoryInfo) {\r
+        try {\r
+            container.run(true, true, new IRunnableWithProgress() {\r
+                @Override\r
+                public void run(IProgressMonitor monitor)\r
+                        throws InvocationTargetException, InterruptedException {\r
+                    executeCloneOperation(cloneOperation, repositoryInfo, monitor);\r
+                }\r
+            });\r
+        } catch (InvocationTargetException e) {\r
+            Activator.handleError(UIText.GitCloneWizard_failed, e.getCause(),\r
+                    true);\r
+        } catch (InterruptedException e) {\r
+            // nothing to do\r
+        }\r
+    }\r
+\r
+    private void runAsJob(final URIish uri, final CloneOperation op,\r
+            final GitRepositoryInfo repositoryInfo) {\r
+        final Job job = new Job(NLS.bind(UIText.GitCloneWizard_jobName,\r
+                uri.toString())) {\r
+            @Override\r
+            protected IStatus run(final IProgressMonitor monitor) {\r
+                try {\r
+                    return executeCloneOperation(op, repositoryInfo, monitor);\r
+                } catch (InterruptedException e) {\r
+                    return Status.CANCEL_STATUS;\r
+                } catch (InvocationTargetException e) {\r
+                    Throwable thr = e.getCause();\r
+                    return new Status(IStatus.ERROR, Activator.getPluginId(),\r
+                            0, thr.getMessage(), thr);\r
+                }\r
+            }\r
+\r
+            @Override\r
+            public boolean belongsTo(Object family) {\r
+                if (JobFamilies.CLONE.equals(family))\r
+                    return true;\r
+                return super.belongsTo(family);\r
+            }\r
+        };\r
+        job.setUser(true);\r
+        job.schedule();\r
+    }\r
+\r
+    private IStatus executeCloneOperation(final CloneOperation op,\r
+            final GitRepositoryInfo repositoryInfo,\r
+            final IProgressMonitor monitor) throws InvocationTargetException,\r
+            InterruptedException {\r
+\r
+        final RepositoryUtil util = Activator.getDefault().getRepositoryUtil();\r
+\r
+        op.run(monitor);\r
+        util.addConfiguredRepository(op.getGitDir());\r
+        try {\r
+            if (repositoryInfo.shouldSaveCredentialsInSecureStore())\r
+                SecureStoreUtils.storeCredentials(repositoryInfo.getCredentials(),\r
+                        new URIish(repositoryInfo.getCloneUri()));\r
+        } catch (Exception e) {\r
+            Activator.error(e.getMessage(), e);\r
+        }\r
+        return Status.OK_STATUS;\r
+    }\r
+\r
+    /**\r
+     * @param newValue if true the clone wizard just creates a clone operation. The caller has to run this operation using runCloneOperation. If false the clone operation is performed using a job.\r
+     */\r
+    public void setCallerRunsCloneOperation(boolean newValue) {\r
+        callerRunsCloneOperation = newValue;\r
+    }\r
+\r
+}\r
diff --git a/rt-ide/tizen.rt.product.plugin/src/org/eclipse/egit/ui/internal/clone/RtCloneDestinationPage.java b/rt-ide/tizen.rt.product.plugin/src/org/eclipse/egit/ui/internal/clone/RtCloneDestinationPage.java
new file mode 100644 (file)
index 0000000..959b3d1
--- /dev/null
@@ -0,0 +1,469 @@
+/*******************************************************************************\r
+ * Copyright (C) 2008, Roger C. Soares <rogersoares@intelinet.com.br>\r
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>\r
+ * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>\r
+ * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>\r
+ * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>\r
+ * Copyright (C) 2013, Robin Stocker <robin@nibor.org>\r
+ *\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *******************************************************************************/\r
+package org.eclipse.egit.ui.internal.clone;\r
+\r
+import java.io.File;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.eclipse.egit.core.RepositoryUtil;\r
+import org.eclipse.egit.ui.Activator;\r
+import org.eclipse.egit.ui.UIPreferences;\r
+import org.eclipse.egit.ui.internal.UIText;\r
+import org.eclipse.egit.ui.internal.components.RepositorySelection;\r
+import org.eclipse.jface.dialogs.Dialog;\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.viewers.ArrayContentProvider;\r
+import org.eclipse.jface.viewers.ComboViewer;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.jface.viewers.LabelProvider;\r
+import org.eclipse.jface.viewers.StructuredSelection;\r
+import org.eclipse.jface.wizard.WizardPage;\r
+import org.eclipse.jgit.lib.Constants;\r
+import org.eclipse.jgit.lib.Ref;\r
+import org.eclipse.jgit.lib.Repository;\r
+import org.eclipse.osgi.util.NLS;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.ModifyEvent;\r
+import org.eclipse.swt.events.ModifyListener;\r
+import org.eclipse.swt.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.FileDialog;\r
+import org.eclipse.swt.widgets.Group;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.eclipse.ui.IWorkingSet;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.eclipse.ui.dialogs.WorkingSetGroup;\r
+\r
+/**\r
+ * Wizard page that allows the user entering the location of a repository to be cloned.\r
+ */\r
+public class RtCloneDestinationPage extends WizardPage {\r
+\r
+    private final List<Ref> availableRefs = new ArrayList<Ref>();\r
+\r
+    private RepositorySelection validatedRepoSelection;\r
+\r
+    private List<Ref> validatedSelectedBranches;\r
+\r
+    private Ref validatedHEAD;\r
+\r
+    private boolean showProjectImport;\r
+\r
+    private ComboViewer initialBranch;\r
+\r
+    private Text directoryText;\r
+\r
+    private Text remoteText;\r
+\r
+    private Button importProjectsButton;\r
+\r
+    private Button cloneSubmodulesButton;\r
+\r
+    private WorkingSetGroup workingSetGroup;\r
+\r
+    private String helpContext = null;\r
+\r
+    private File clonedDestination;\r
+\r
+    private Ref clonedInitialBranch;\r
+\r
+    private String clonedRemote;\r
+\r
+    RtCloneDestinationPage() {\r
+        super(RtCloneDestinationPage.class.getName());\r
+        setTitle(UIText.CloneDestinationPage_title);\r
+    }\r
+\r
+    @Override\r
+    public void createControl(final Composite parent) {\r
+        final Composite panel = new Composite(parent, SWT.NULL);\r
+        final GridLayout layout = new GridLayout();\r
+        layout.numColumns = 1;\r
+        panel.setLayout(layout);\r
+\r
+        createDestinationGroup(panel);\r
+        createConfigGroup(panel);\r
+        if (showProjectImport)\r
+            createProjectGroup(panel);\r
+\r
+        Dialog.applyDialogFont(panel);\r
+        setControl(panel);\r
+        checkPage();\r
+    }\r
+\r
+    @Override\r
+    public void setVisible(final boolean visible) {\r
+        if (visible)\r
+            if (this.availableRefs.isEmpty())\r
+                initialBranch.getCombo().setEnabled(false);\r
+        super.setVisible(visible);\r
+        if (visible)\r
+            directoryText.setFocus();\r
+    }\r
+\r
+    /**\r
+     * @param repositorySelection selection of remote repository made by user\r
+     * @param availableRefs all available refs\r
+     * @param branches branches selected to be cloned\r
+     * @param head HEAD in source repository\r
+     */\r
+    public void setSelection(RepositorySelection repositorySelection, List<Ref> availableRefs, List<Ref> branches, Ref head) {\r
+        this.availableRefs.clear();\r
+        this.availableRefs.addAll(availableRefs);\r
+        checkPreviousPagesSelections(repositorySelection, branches, head);\r
+        revalidate(repositorySelection, branches, head);\r
+    }\r
+\r
+    private void checkPreviousPagesSelections(\r
+            RepositorySelection repositorySelection, List<Ref> branches,\r
+            Ref head) {\r
+        if (!repositorySelection.equals(validatedRepoSelection)\r
+                || !branches.equals(validatedSelectedBranches)\r
+                || !head.equals(validatedHEAD))\r
+            setPageComplete(false);\r
+        else\r
+            checkPage();\r
+    }\r
+\r
+    private void createDestinationGroup(final Composite parent) {\r
+        final Group g = createGroup(parent,\r
+                UIText.CloneDestinationPage_groupDestination);\r
+\r
+        Label dirLabel = new Label(g, SWT.NONE);\r
+        dirLabel.setText(UIText.CloneDestinationPage_promptDirectory + ":"); //$NON-NLS-1$\r
+        dirLabel\r
+                .setToolTipText(UIText.CloneDestinationPage_DefaultRepoFolderTooltip);\r
+        final Composite p = new Composite(g, SWT.NONE);\r
+        final GridLayout grid = new GridLayout();\r
+        grid.numColumns = 2;\r
+        p.setLayout(grid);\r
+        p.setLayoutData(createFieldGridData());\r
+        directoryText = new Text(p, SWT.BORDER);\r
+        directoryText.setLayoutData(createFieldGridData());\r
+        directoryText.addModifyListener(new ModifyListener() {\r
+            @Override\r
+            public void modifyText(final ModifyEvent e) {\r
+                checkPage();\r
+            }\r
+        });\r
+        final Button b = new Button(p, SWT.PUSH);\r
+        b.setText(UIText.CloneDestinationPage_browseButton);\r
+        b.addSelectionListener(new SelectionAdapter() {\r
+            @Override\r
+            public void widgetSelected(final SelectionEvent e) {\r
+                final FileDialog d;\r
+\r
+                d = new FileDialog(getShell(), SWT.APPLICATION_MODAL | SWT.SAVE);\r
+                if (directoryText.getText().length() > 0) {\r
+                    final File file = new File(directoryText.getText())\r
+                            .getAbsoluteFile();\r
+                    d.setFilterPath(file.getParent());\r
+                    d.setFileName(file.getName());\r
+                }\r
+                final String r = d.open();\r
+                if (r != null)\r
+                    directoryText.setText(r);\r
+            }\r
+        });\r
+\r
+        newLabel(g, UIText.CloneDestinationPage_promptInitialBranch + ":"); //$NON-NLS-1$\r
+        initialBranch = new ComboViewer(g, SWT.DROP_DOWN | SWT.READ_ONLY);\r
+        initialBranch.getCombo().setLayoutData(createFieldGridData());\r
+        initialBranch.getCombo().addSelectionListener(new SelectionAdapter() {\r
+            @Override\r
+            public void widgetSelected(final SelectionEvent e) {\r
+                checkPage();\r
+            }\r
+        });\r
+        initialBranch.setContentProvider(ArrayContentProvider.getInstance());\r
+        initialBranch.setLabelProvider(new LabelProvider() {\r
+            @Override\r
+            public String getText(Object element) {\r
+                if (((Ref) element).getName().startsWith(Constants.R_HEADS))\r
+                    return ((Ref) element).getName().substring(Constants.R_HEADS.length());\r
+                return ((Ref) element).getName();\r
+            }\r
+        });\r
+\r
+        cloneSubmodulesButton = new Button(g, SWT.CHECK);\r
+        cloneSubmodulesButton\r
+                .setText(UIText.CloneDestinationPage_cloneSubmodulesButton);\r
+        GridDataFactory.swtDefaults().span(2, 1).applyTo(cloneSubmodulesButton);\r
+    }\r
+\r
+    private void createConfigGroup(final Composite parent) {\r
+        final Group g = createGroup(parent,\r
+                UIText.CloneDestinationPage_groupConfiguration);\r
+\r
+        newLabel(g, UIText.CloneDestinationPage_promptRemoteName + ":"); //$NON-NLS-1$\r
+        remoteText = new Text(g, SWT.BORDER);\r
+        remoteText.setText(Constants.DEFAULT_REMOTE_NAME);\r
+        remoteText.setLayoutData(createFieldGridData());\r
+        remoteText.addModifyListener(new ModifyListener() {\r
+            @Override\r
+            public void modifyText(ModifyEvent e) {\r
+                checkPage();\r
+            }\r
+        });\r
+    }\r
+\r
+    private void createProjectGroup(final Composite parent) {\r
+        final Group group = createGroup(parent,\r
+                UIText.CloneDestinationPage_groupProjects);\r
+\r
+        GridLayoutFactory.swtDefaults().applyTo(group);\r
+        importProjectsButton = new Button(group, SWT.CHECK);\r
+        importProjectsButton.setText(UIText.CloneDestinationPage_importButton);\r
+        importProjectsButton.setSelection(Activator.getDefault()\r
+                .getPreferenceStore()\r
+                .getBoolean(UIPreferences.CLONE_WIZARD_IMPORT_PROJECTS));\r
+        importProjectsButton.addSelectionListener(new SelectionAdapter() {\r
+            @Override\r
+            public void widgetSelected(SelectionEvent e) {\r
+                Activator\r
+                        .getDefault()\r
+                        .getPreferenceStore()\r
+                        .setValue(UIPreferences.CLONE_WIZARD_IMPORT_PROJECTS,\r
+                                importProjectsButton.getSelection());\r
+            }\r
+        });\r
+\r
+        // TODO: replace hardcoded ids once bug 245106 is fixed\r
+        String[] workingSetTypes = new String[] {\r
+                "org.eclipse.ui.resourceWorkingSetPage", //$NON-NLS-1$\r
+                "org.eclipse.jdt.ui.JavaWorkingSetPage" //$NON-NLS-1$\r
+        };\r
+        workingSetGroup = new WorkingSetGroup(group, null, workingSetTypes);\r
+    }\r
+\r
+    private static Group createGroup(final Composite parent, final String text) {\r
+        final Group g = new Group(parent, SWT.NONE);\r
+        final GridLayout layout = new GridLayout();\r
+        layout.numColumns = 2;\r
+        g.setLayout(layout);\r
+        g.setText(text);\r
+        final GridData gd = new GridData();\r
+        gd.grabExcessHorizontalSpace = true;\r
+        gd.horizontalAlignment = SWT.FILL;\r
+        g.setLayoutData(gd);\r
+        return g;\r
+    }\r
+\r
+    private static void newLabel(final Group g, final String text) {\r
+        new Label(g, SWT.NULL).setText(text);\r
+    }\r
+\r
+    private static GridData createFieldGridData() {\r
+        return new GridData(SWT.FILL, SWT.DEFAULT, true, false);\r
+    }\r
+\r
+    /**\r
+     * @return true to import projects, false otherwise\r
+     */\r
+    public boolean isImportProjects() {\r
+        return importProjectsButton != null\r
+                && importProjectsButton.getSelection();\r
+    }\r
+\r
+    /**\r
+     * @return true to clone submodules, false otherwise\r
+     */\r
+    public boolean isCloneSubmodules() {\r
+        return cloneSubmodulesButton != null\r
+                && cloneSubmodulesButton.getSelection();\r
+    }\r
+\r
+    /**\r
+     * @return selected working sets\r
+     */\r
+    public IWorkingSet[] getWorkingSets() {\r
+        if (workingSetGroup == null)\r
+            return new IWorkingSet[0];\r
+        return workingSetGroup.getSelectedWorkingSets();\r
+    }\r
+\r
+    /**\r
+     * @return location the user wants to store this repository.\r
+     */\r
+    public File getDestinationFile() {\r
+        return new File(directoryText.getText());\r
+    }\r
+\r
+    /**\r
+     * @return initial branch selected (includes refs/heads prefix).\r
+     */\r
+    public Ref getInitialBranch() {\r
+        IStructuredSelection selection = (IStructuredSelection) initialBranch.getSelection();\r
+        return (Ref) selection.getFirstElement();\r
+    }\r
+\r
+    /**\r
+     * @return remote name\r
+     */\r
+    public String getRemote() {\r
+        return remoteText.getText().trim();\r
+    }\r
+\r
+    /**\r
+     * Set the ID for context sensitive help\r
+     * @param id help context\r
+     */\r
+    public void setHelpContext(String id) {\r
+        helpContext = id;\r
+    }\r
+\r
+    @Override\r
+    public void performHelp() {\r
+        PlatformUI.getWorkbench().getHelpSystem().displayHelp(helpContext);\r
+    }\r
+\r
+    /**\r
+     * Check internal state for page completion status.\r
+     */\r
+    private void checkPage() {\r
+        if (!cloneSettingsChanged()) {\r
+            setErrorMessage(null);\r
+            setPageComplete(true);\r
+            return;\r
+        }\r
+        final String dstpath = directoryText.getText();\r
+        if (dstpath.length() == 0) {\r
+            setErrorMessage(UIText.CloneDestinationPage_errorDirectoryRequired);\r
+            setPageComplete(false);\r
+            return;\r
+        }\r
+        final File absoluteFile = new File(dstpath).getAbsoluteFile();\r
+        if (!isEmptyDir(absoluteFile)) {\r
+            setErrorMessage(NLS.bind(\r
+                    UIText.CloneDestinationPage_errorNotEmptyDir, absoluteFile\r
+                            .getPath()));\r
+            setPageComplete(false);\r
+            return;\r
+        }\r
+\r
+        if (!canCreateSubdir(absoluteFile.getParentFile())) {\r
+            setErrorMessage(NLS.bind(UIText.GitCloneWizard_errorCannotCreate,\r
+                    absoluteFile.getPath()));\r
+            setPageComplete(false);\r
+            return;\r
+        }\r
+        if (!availableRefs.isEmpty()\r
+                && initialBranch.getCombo().getSelectionIndex() < 0) {\r
+            setErrorMessage(UIText.CloneDestinationPage_errorInitialBranchRequired);\r
+            setPageComplete(false);\r
+            return;\r
+        }\r
+        String remoteName = getRemote();\r
+        if (remoteName.length() == 0) {\r
+            setErrorMessage(UIText.CloneDestinationPage_errorRemoteNameRequired);\r
+            setPageComplete(false);\r
+            return;\r
+        }\r
+        if (!Repository.isValidRefName(Constants.R_REMOTES + remoteName)) {\r
+            setErrorMessage(NLS.bind(\r
+                    UIText.CloneDestinationPage_errorInvalidRemoteName,\r
+                    remoteName));\r
+            setPageComplete(false);\r
+            return;\r
+        }\r
+\r
+        setErrorMessage(null);\r
+        setPageComplete(true);\r
+    }\r
+\r
+    void saveSettingsForClonedRepo() {\r
+        clonedDestination = getDestinationFile();\r
+        clonedInitialBranch = getInitialBranch();\r
+        clonedRemote = getRemote();\r
+    }\r
+\r
+    /**\r
+     * @return whether user updated clone settings\r
+     * @since 4.0.0\r
+     */\r
+    public boolean cloneSettingsChanged() {\r
+        boolean cloneSettingsChanged = false;\r
+        if (clonedDestination == null || !clonedDestination.equals(getDestinationFile()) ||\r
+                clonedInitialBranch == null || !clonedInitialBranch.equals(getInitialBranch()) ||\r
+                clonedRemote == null || !clonedRemote.equals(getRemote()))\r
+            cloneSettingsChanged = true;\r
+        return cloneSettingsChanged;\r
+    }\r
+\r
+    private static boolean isEmptyDir(final File dir) {\r
+        if (!dir.exists())\r
+            return true;\r
+        if (!dir.isDirectory())\r
+            return false;\r
+        return dir.listFiles().length == 0;\r
+    }\r
+\r
+    // this is actually just an optimistic heuristic - should be named\r
+    // isThereHopeThatCanCreateSubdir() as probably there is no 100% reliable\r
+    // way to check that in Java for Windows\r
+    private static boolean canCreateSubdir(final File parent) {\r
+        if (parent == null)\r
+            return true;\r
+        if (parent.exists())\r
+            return parent.isDirectory() && parent.canWrite();\r
+        return canCreateSubdir(parent.getParentFile());\r
+    }\r
+\r
+    private void revalidate(RepositorySelection repoSelection, List<Ref> branches, Ref head) {\r
+        if (repoSelection.equals(validatedRepoSelection)\r
+                && branches.equals(validatedSelectedBranches)\r
+                && head.equals(validatedHEAD)) {\r
+            checkPage();\r
+            return;\r
+        }\r
+\r
+        if (!repoSelection.equals(validatedRepoSelection)) {\r
+            validatedRepoSelection = repoSelection;\r
+            // update repo-related selection only if it changed\r
+            final String n = validatedRepoSelection.getURI().getHumanishName();\r
+            setDescription(NLS.bind(UIText.CloneDestinationPage_description, n));\r
+            String defaultRepoDir = RepositoryUtil.getDefaultRepositoryDir();\r
+            File parentDir = new File(defaultRepoDir);\r
+            directoryText.setText(new File(parentDir, n).getAbsolutePath());\r
+        }\r
+\r
+        validatedSelectedBranches = branches;\r
+        validatedHEAD = head;\r
+\r
+        initialBranch.setInput(branches);\r
+        if (head != null && branches.contains(head))\r
+            initialBranch.setSelection(new StructuredSelection(head));\r
+        else if (branches.size() > 0)\r
+            initialBranch\r
+                    .setSelection(new StructuredSelection(branches.get(0)));\r
+        checkPage();\r
+    }\r
+\r
+    /**\r
+     * Set whether to show project import options\r
+     * @param show\r
+     * @return this wizard page\r
+     */\r
+    public RtCloneDestinationPage setShowProjectImport(boolean show) {\r
+        showProjectImport = show;\r
+        return this;\r
+    }\r
+}\r
index b2300f0..dec4a1a 100644 (file)
@@ -61,7 +61,7 @@ import org.tizen.rt.product.RtProjectNature;
 /**
  * A wizard which allows to optionally clone a repository and to import projects from a repository.
  */
-public class RtGitImportWizard extends AbstractGitCloneWizard implements IImportWizard {
+public class RtGitImportWizard extends AbstractRtGitCloneWizard implements IImportWizard {
 
     private static final Logger logger = LoggerFactory.getLogger(RtGitImportWizard.class);
 
@@ -218,6 +218,8 @@ public class RtGitImportWizard extends AbstractGitCloneWizard implements IImport
                             break;
                         }
                     }
+
+                    // Modified
                     if (project != null) {
                         try {
                             RtProjectNature.makeRtProject(project, monitor);
diff --git a/rt-ide/tizen.rt.product.plugin/src/org/eclipse/egit/ui/internal/clone/RtSourceBranchPage.java b/rt-ide/tizen.rt.product.plugin/src/org/eclipse/egit/ui/internal/clone/RtSourceBranchPage.java
new file mode 100644 (file)
index 0000000..37bbf9b
--- /dev/null
@@ -0,0 +1,418 @@
+/*******************************************************************************\r
+ * Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>\r
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>\r
+ * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>\r
+ * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>\r
+ * Copyright (c) 2010, Benjamin Muskalla <bmuskalla@eclipsesource.com>\r
+ * Copyright (c) 2012, IBM Corporation\r
+ *\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *******************************************************************************/\r
+package org.eclipse.egit.ui.internal.clone;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.lang.reflect.InvocationTargetException;\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.Collections;\r
+import java.util.Comparator;\r
+import java.util.List;\r
+\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;\r
+import org.eclipse.core.runtime.jobs.JobChangeAdapter;\r
+import org.eclipse.egit.core.op.ListRemoteOperation;\r
+import org.eclipse.egit.core.securestorage.UserPasswordCredentials;\r
+import org.eclipse.egit.ui.Activator;\r
+import org.eclipse.egit.ui.UIPreferences;\r
+import org.eclipse.egit.ui.internal.UIText;\r
+import org.eclipse.egit.ui.internal.components.CachedCheckboxTreeViewer;\r
+import org.eclipse.egit.ui.internal.components.FilteredCheckboxTree;\r
+import org.eclipse.egit.ui.internal.components.RepositorySelection;\r
+import org.eclipse.egit.ui.internal.credentials.EGitCredentialsProvider;\r
+import org.eclipse.egit.ui.internal.dialogs.SourceBranchFailureDialog;\r
+import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNodeType;\r
+import org.eclipse.jface.dialogs.Dialog;\r
+import org.eclipse.jface.dialogs.IMessageProvider;\r
+import org.eclipse.jface.operation.IRunnableWithProgress;\r
+import org.eclipse.jface.viewers.CheckStateChangedEvent;\r
+import org.eclipse.jface.viewers.ICheckStateListener;\r
+import org.eclipse.jface.viewers.ITreeContentProvider;\r
+import org.eclipse.jface.viewers.LabelProvider;\r
+import org.eclipse.jface.viewers.Viewer;\r
+import org.eclipse.jface.wizard.WizardPage;\r
+import org.eclipse.jgit.api.errors.TransportException;\r
+import org.eclipse.jgit.lib.Constants;\r
+import org.eclipse.jgit.lib.Ref;\r
+import org.eclipse.jgit.lib.Repository;\r
+import org.eclipse.jgit.storage.file.FileRepositoryBuilder;\r
+import org.eclipse.jgit.transport.URIish;\r
+import org.eclipse.osgi.util.NLS;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.layout.RowLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.eclipse.ui.dialogs.PatternFilter;\r
+import org.eclipse.ui.progress.WorkbenchJob;\r
+\r
+class RtSourceBranchPage extends WizardPage {\r
+\r
+    private RepositorySelection validatedRepoSelection;\r
+\r
+    private Ref head;\r
+\r
+    private final List<Ref> availableRefs = new ArrayList<Ref>();\r
+\r
+    private Label label;\r
+\r
+    private String transportError;\r
+\r
+    private Button selectB;\r
+\r
+    private Button unselectB;\r
+\r
+    private CachedCheckboxTreeViewer refsViewer;\r
+\r
+    private UserPasswordCredentials credentials;\r
+\r
+    private String helpContext = null;\r
+\r
+    RtSourceBranchPage() {\r
+        super(RtSourceBranchPage.class.getName());\r
+        setTitle(UIText.SourceBranchPage_title);\r
+        setDescription(UIText.SourceBranchPage_description);\r
+    }\r
+\r
+    List<Ref> getSelectedBranches() {\r
+        Object[] checkedElements = refsViewer.getCheckedElements();\r
+        Ref[] checkedRefs = new Ref[checkedElements.length];\r
+        System.arraycopy(checkedElements, 0, checkedRefs, 0, checkedElements.length);\r
+        return Arrays.asList(checkedRefs);\r
+    }\r
+\r
+    List<Ref> getAvailableBranches() {\r
+        return availableRefs;\r
+    }\r
+\r
+    Ref getHEAD() {\r
+        return head;\r
+    }\r
+\r
+    boolean isSourceRepoEmpty() {\r
+        return availableRefs.isEmpty();\r
+    }\r
+\r
+    boolean isAllSelected() {\r
+        return availableRefs.size() == refsViewer.getCheckedElements().length;\r
+    }\r
+\r
+    @Override\r
+    public void createControl(final Composite parent) {\r
+        final Composite panel = new Composite(parent, SWT.NULL);\r
+        final GridLayout layout = new GridLayout();\r
+        layout.numColumns = 1;\r
+        panel.setLayout(layout);\r
+\r
+        label = new Label(panel, SWT.NONE);\r
+        label.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));\r
+\r
+        FilteredCheckboxTree fTree = new FilteredCheckboxTree(panel, null,\r
+                SWT.NONE, new PatternFilter()) {\r
+            /*\r
+             * Overridden to check page when refreshing is done.\r
+             */\r
+            @Override\r
+            protected WorkbenchJob doCreateRefreshJob() {\r
+                WorkbenchJob refreshJob = super.doCreateRefreshJob();\r
+                refreshJob.addJobChangeListener(new JobChangeAdapter() {\r
+                    @Override\r
+                    public void done(IJobChangeEvent event) {\r
+                        if (event.getResult().isOK()) {\r
+                            getDisplay().asyncExec(new Runnable() {\r
+                                @Override\r
+                                public void run() {\r
+                                    checkPage();\r
+                                }\r
+                            });\r
+                        }\r
+                    }\r
+                });\r
+                return refreshJob;\r
+            }\r
+        };\r
+        refsViewer = fTree.getCheckboxTreeViewer();\r
+\r
+        ITreeContentProvider provider = new ITreeContentProvider() {\r
+\r
+            @Override\r
+            public void inputChanged(Viewer arg0, Object arg1, Object arg2) {\r
+                // nothing\r
+            }\r
+\r
+            @Override\r
+            public void dispose() {\r
+                // nothing\r
+            }\r
+\r
+            @Override\r
+            public Object[] getElements(Object input) {\r
+                return ((List) input).toArray();\r
+            }\r
+\r
+            @Override\r
+            public boolean hasChildren(Object element) {\r
+                return false;\r
+            }\r
+\r
+            @Override\r
+            public Object getParent(Object element) {\r
+                return null;\r
+            }\r
+\r
+            @Override\r
+            public Object[] getChildren(Object parentElement) {\r
+                return null;\r
+            }\r
+        };\r
+        refsViewer.setContentProvider(provider);\r
+        refsViewer.setLabelProvider(new LabelProvider() {\r
+            @Override\r
+            public String getText(Object element) {\r
+                if (((Ref) element).getName().startsWith(Constants.R_HEADS))\r
+                    return ((Ref) element).getName().substring(Constants.R_HEADS.length());\r
+                return ((Ref) element).getName();\r
+            }\r
+\r
+            @Override\r
+            public Image getImage(Object element) {\r
+                return RepositoryTreeNodeType.REF.getIcon();\r
+            }\r
+        });\r
+\r
+        refsViewer.addCheckStateListener(new ICheckStateListener() {\r
+            @Override\r
+            public void checkStateChanged(CheckStateChangedEvent event) {\r
+                checkPage();\r
+            }\r
+        });\r
+        final Composite bPanel = new Composite(panel, SWT.NONE);\r
+        bPanel.setLayout(new RowLayout());\r
+        selectB = new Button(bPanel, SWT.PUSH);\r
+        selectB.setText(UIText.SourceBranchPage_selectAll);\r
+        selectB.addSelectionListener(new SelectionAdapter() {\r
+            @Override\r
+            public void widgetSelected(final SelectionEvent e) {\r
+                refsViewer.setAllChecked(true);\r
+                checkPage();\r
+            }\r
+        });\r
+        unselectB = new Button(bPanel, SWT.PUSH);\r
+        unselectB.setText(UIText.SourceBranchPage_selectNone);\r
+        unselectB.addSelectionListener(new SelectionAdapter() {\r
+            @Override\r
+            public void widgetSelected(final SelectionEvent e) {\r
+                refsViewer.setAllChecked(false);\r
+                checkPage();\r
+            }\r
+        });\r
+        bPanel.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));\r
+\r
+        Dialog.applyDialogFont(panel);\r
+        setControl(panel);\r
+        checkPage();\r
+    }\r
+\r
+    public void setSelection(RepositorySelection selection) {\r
+        revalidate(selection);\r
+    }\r
+\r
+    public void setCredentials(UserPasswordCredentials credentials) {\r
+        this.credentials = credentials;\r
+    }\r
+\r
+    /**\r
+     * Set the ID for context sensitive help\r
+     * @param id help context\r
+     */\r
+    public void setHelpContext(String id) {\r
+        helpContext = id;\r
+    }\r
+\r
+    @Override\r
+    public void performHelp() {\r
+        PlatformUI.getWorkbench().getHelpSystem().displayHelp(helpContext);\r
+    }\r
+\r
+    /**\r
+     * Check internal state for page completion status. This method should be called only when all necessary data from previous form is available.\r
+     */\r
+    private void checkPage() {\r
+        setMessage(null);\r
+        int checkedElementCount = refsViewer.getCheckedElements().length;\r
+        selectB.setEnabled(checkedElementCount != availableRefs.size());\r
+        unselectB.setEnabled(checkedElementCount != 0);\r
+        if (transportError != null) {\r
+            setErrorMessage(transportError);\r
+            setPageComplete(false);\r
+            return;\r
+        }\r
+\r
+        if (getSelectedBranches().isEmpty()) {\r
+            setErrorMessage(UIText.SourceBranchPage_errorBranchRequired);\r
+            setPageComplete(false);\r
+            return;\r
+        }\r
+        setErrorMessage(null);\r
+        setPageComplete(true);\r
+    }\r
+\r
+    private void checkForEmptyRepo() {\r
+        if (isSourceRepoEmpty()) {\r
+            setErrorMessage(null);\r
+            setMessage(UIText.SourceBranchPage_repoEmpty, IMessageProvider.WARNING);\r
+            setPageComplete(true);\r
+        }\r
+    }\r
+\r
+    private void revalidate(final RepositorySelection newRepoSelection) {\r
+        if (newRepoSelection.equals(validatedRepoSelection)) {\r
+            // URI hasn't changed, no need to refill the page with new data\r
+            checkPage();\r
+            return;\r
+        }\r
+\r
+        label.setText(NLS.bind(UIText.SourceBranchPage_branchList,\r
+                newRepoSelection.getURI().toString()));\r
+        label.getParent().layout();\r
+\r
+        validatedRepoSelection = null;\r
+        transportError = null;\r
+        head = null;\r
+        availableRefs.clear();\r
+        refsViewer.setInput(null);\r
+        setPageComplete(false);\r
+        setErrorMessage(null);\r
+        setMessage(null);\r
+        label.getDisplay().asyncExec(new Runnable() {\r
+            @Override\r
+            public void run() {\r
+                revalidateImpl(newRepoSelection);\r
+            }\r
+        });\r
+    }\r
+\r
+    private void revalidateImpl(final RepositorySelection newRepoSelection) {\r
+        if (label.isDisposed() || !isCurrentPage())\r
+            return;\r
+\r
+        final ListRemoteOperation listRemoteOp;\r
+        final URIish uri = newRepoSelection.getURI();\r
+        try {\r
+            final Repository db = FileRepositoryBuilder\r
+                    .create(new File("/tmp")); //$NON-NLS-1$\r
+            int timeout = Activator.getDefault().getPreferenceStore().getInt(\r
+                    UIPreferences.REMOTE_CONNECTION_TIMEOUT);\r
+            listRemoteOp = new ListRemoteOperation(db, uri, timeout);\r
+            if (credentials != null)\r
+                listRemoteOp\r
+                        .setCredentialsProvider(new EGitCredentialsProvider(\r
+                                credentials.getUser(), credentials\r
+                                        .getPassword()));\r
+            getContainer().run(true, true, new IRunnableWithProgress() {\r
+                @Override\r
+                public void run(IProgressMonitor monitor)\r
+                        throws InvocationTargetException, InterruptedException {\r
+                    listRemoteOp.run(monitor);\r
+                }\r
+            });\r
+        } catch (InvocationTargetException e) {\r
+            Throwable why = e.getCause();\r
+            transportError(why);\r
+            if (showDetailedFailureDialog())\r
+                SourceBranchFailureDialog.show(getShell(), uri);\r
+            return;\r
+        } catch (IOException e) {\r
+            transportError(UIText.SourceBranchPage_cannotCreateTemp);\r
+            return;\r
+        } catch (InterruptedException e) {\r
+            transportError(UIText.SourceBranchPage_remoteListingCancelled);\r
+            return;\r
+        }\r
+\r
+        final Ref idHEAD = listRemoteOp.getRemoteRef(Constants.HEAD);\r
+        head = null;\r
+        boolean headIsMaster = false;\r
+        final String masterBranchRef = Constants.R_HEADS + Constants.MASTER;\r
+        for (final Ref r : listRemoteOp.getRemoteRefs()) {\r
+            final String n = r.getName();\r
+            if (!n.startsWith(Constants.R_HEADS))\r
+                continue;\r
+            availableRefs.add(r);\r
+            if (idHEAD == null || headIsMaster)\r
+                continue;\r
+            if (r.getObjectId().equals(idHEAD.getObjectId())) {\r
+                headIsMaster = masterBranchRef.equals(r.getName());\r
+                if (head == null || headIsMaster)\r
+                    head = r;\r
+            }\r
+        }\r
+        Collections.sort(availableRefs, new Comparator<Ref>() {\r
+            @Override\r
+            public int compare(final Ref o1, final Ref o2) {\r
+                return o1.getName().compareTo(o2.getName());\r
+            }\r
+        });\r
+        if (idHEAD != null && head == null) {\r
+            head = idHEAD;\r
+            availableRefs.add(0, idHEAD);\r
+        }\r
+\r
+        validatedRepoSelection = newRepoSelection;\r
+        refsViewer.setInput(availableRefs);\r
+        refsViewer.setAllChecked(true);\r
+        checkPage();\r
+        checkForEmptyRepo();\r
+    }\r
+\r
+    private void transportError(final Throwable why) {\r
+        Activator.logError(why.getMessage(), why);\r
+        Throwable cause = why.getCause();\r
+        if (why instanceof TransportException && cause != null)\r
+            transportError(NLS.bind(getMessage(why), why.getMessage(),\r
+                    cause.getMessage()));\r
+        else\r
+            transportError(why.getMessage());\r
+    }\r
+\r
+    private String getMessage(final Throwable why) {\r
+        if (why.getMessage().endsWith("Auth fail")) //$NON-NLS-1$\r
+            return UIText.SourceBranchPage_AuthFailMessage;\r
+        else\r
+            return UIText.SourceBranchPage_CompositeTransportErrorMessage;\r
+    }\r
+\r
+    private void transportError(final String msg) {\r
+        transportError = msg;\r
+        checkPage();\r
+    }\r
+\r
+    private boolean showDetailedFailureDialog() {\r
+        return Activator\r
+                .getDefault()\r
+                .getPreferenceStore()\r
+                .getBoolean(\r
+                        UIPreferences.CLONE_WIZARD_SHOW_DETAILED_FAILURE_DIALOG);\r
+    }\r
+\r
+}\r