LsRemoteCommand.java

  1. /*
  2.  * Copyright (C) 2011, Christoph Brill <egore911@egore911.de>
  3.  * and other copyright owners as documented in the project's IP log.
  4.  *
  5.  * This program and the accompanying materials are made available
  6.  * under the terms of the Eclipse Distribution License v1.0 which
  7.  * accompanies this distribution, is reproduced below, and is
  8.  * available at http://www.eclipse.org/org/documents/edl-v10.php
  9.  *
  10.  * All rights reserved.
  11.  *
  12.  * Redistribution and use in source and binary forms, with or
  13.  * without modification, are permitted provided that the following
  14.  * conditions are met:
  15.  *
  16.  * - Redistributions of source code must retain the above copyright
  17.  *   notice, this list of conditions and the following disclaimer.
  18.  *
  19.  * - Redistributions in binary form must reproduce the above
  20.  *   copyright notice, this list of conditions and the following
  21.  *   disclaimer in the documentation and/or other materials provided
  22.  *   with the distribution.
  23.  *
  24.  * - Neither the name of the Eclipse Foundation, Inc. nor the
  25.  *   names of its contributors may be used to endorse or promote
  26.  *   products derived from this software without specific prior
  27.  *   written permission.
  28.  *
  29.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  30.  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  31.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  32.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  33.  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  34.  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  35.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  36.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  37.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  38.  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  40.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  41.  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  42.  */
  43. package org.eclipse.jgit.api;

  44. import java.net.URISyntaxException;
  45. import java.text.MessageFormat;
  46. import java.util.ArrayList;
  47. import java.util.Collection;
  48. import java.util.Collections;
  49. import java.util.HashMap;
  50. import java.util.Map;

  51. import org.eclipse.jgit.api.errors.GitAPIException;
  52. import org.eclipse.jgit.api.errors.InvalidRemoteException;
  53. import org.eclipse.jgit.api.errors.JGitInternalException;
  54. import org.eclipse.jgit.errors.NotSupportedException;
  55. import org.eclipse.jgit.errors.TransportException;
  56. import org.eclipse.jgit.internal.JGitText;
  57. import org.eclipse.jgit.lib.Constants;
  58. import org.eclipse.jgit.lib.Ref;
  59. import org.eclipse.jgit.lib.Repository;
  60. import org.eclipse.jgit.transport.FetchConnection;
  61. import org.eclipse.jgit.transport.RefSpec;
  62. import org.eclipse.jgit.transport.Transport;
  63. import org.eclipse.jgit.transport.URIish;

  64. /**
  65.  * The ls-remote command
  66.  *
  67.  * @see <a
  68.  *      href="http://www.kernel.org/pub/software/scm/git/docs/git-ls-remote.html"
  69.  *      >Git documentation about ls-remote</a>
  70.  */
  71. public class LsRemoteCommand extends
  72.         TransportCommand<LsRemoteCommand, Collection<Ref>> {

  73.     private String remote = Constants.DEFAULT_REMOTE_NAME;

  74.     private boolean heads;

  75.     private boolean tags;

  76.     private String uploadPack;

  77.     /**
  78.      * Constructor for LsRemoteCommand
  79.      *
  80.      * @param repo
  81.      *            local repository or null for operation without local
  82.      *            repository
  83.      */
  84.     public LsRemoteCommand(Repository repo) {
  85.         super(repo);
  86.     }

  87.     /**
  88.      * The remote (uri or name) used for the fetch operation. If no remote is
  89.      * set, the default value of <code>Constants.DEFAULT_REMOTE_NAME</code> will
  90.      * be used.
  91.      *
  92.      * @see Constants#DEFAULT_REMOTE_NAME
  93.      * @param remote
  94.      *            a {@link java.lang.String} object.
  95.      * @return {@code this}
  96.      */
  97.     public LsRemoteCommand setRemote(String remote) {
  98.         checkCallable();
  99.         this.remote = remote;
  100.         return this;
  101.     }

  102.     /**
  103.      * Include refs/heads in references results
  104.      *
  105.      * @param heads
  106.      *            whether to include refs/heads
  107.      * @return {@code this}
  108.      */
  109.     public LsRemoteCommand setHeads(boolean heads) {
  110.         this.heads = heads;
  111.         return this;
  112.     }

  113.     /**
  114.      * Include refs/tags in references results
  115.      *
  116.      * @param tags
  117.      *            whether to include tags
  118.      * @return {@code this}
  119.      */
  120.     public LsRemoteCommand setTags(boolean tags) {
  121.         this.tags = tags;
  122.         return this;
  123.     }

  124.     /**
  125.      * The full path of git-upload-pack on the remote host
  126.      *
  127.      * @param uploadPack
  128.      *            the full path of executable providing the git-upload-pack
  129.      *            service on remote host
  130.      * @return {@code this}
  131.      */
  132.     public LsRemoteCommand setUploadPack(String uploadPack) {
  133.         this.uploadPack = uploadPack;
  134.         return this;
  135.     }

  136.     /**
  137.      * {@inheritDoc}
  138.      * <p>
  139.      * Execute the {@code LsRemote} command with all the options and parameters
  140.      * collected by the setter methods (e.g. {@link #setHeads(boolean)}) of this
  141.      * class. Each instance of this class should only be used for one invocation
  142.      * of the command. Don't call this method twice on an instance.
  143.      */
  144.     @Override
  145.     public Collection<Ref> call() throws GitAPIException,
  146.             InvalidRemoteException,
  147.             org.eclipse.jgit.api.errors.TransportException {
  148.         return execute().values();
  149.     }

  150.     /**
  151.      * Same as {@link #call()}, but return Map instead of Collection.
  152.      *
  153.      * @return a map from names to references in the remote repository
  154.      * @throws org.eclipse.jgit.api.errors.GitAPIException
  155.      *             or subclass thereof when an error occurs
  156.      * @throws org.eclipse.jgit.api.errors.InvalidRemoteException
  157.      *             when called with an invalid remote uri
  158.      * @throws org.eclipse.jgit.api.errors.TransportException
  159.      *             for errors that occurs during transport
  160.      * @since 3.5
  161.      */
  162.     public Map<String, Ref> callAsMap() throws GitAPIException,
  163.             InvalidRemoteException,
  164.             org.eclipse.jgit.api.errors.TransportException {
  165.         return Collections.unmodifiableMap(execute());
  166.     }

  167.     private Map<String, Ref> execute() throws GitAPIException,
  168.             InvalidRemoteException,
  169.             org.eclipse.jgit.api.errors.TransportException {
  170.         checkCallable();

  171.         try (Transport transport = repo != null
  172.                 ? Transport.open(repo, remote)
  173.                 : Transport.open(new URIish(remote))) {
  174.             transport.setOptionUploadPack(uploadPack);
  175.             configure(transport);
  176.             Collection<RefSpec> refSpecs = new ArrayList<>(1);
  177.             if (tags)
  178.                 refSpecs.add(new RefSpec(
  179.                         "refs/tags/*:refs/remotes/origin/tags/*")); //$NON-NLS-1$
  180.             if (heads)
  181.                 refSpecs.add(new RefSpec("refs/heads/*:refs/remotes/origin/*")); //$NON-NLS-1$
  182.             Collection<Ref> refs;
  183.             Map<String, Ref> refmap = new HashMap<>();
  184.             try (FetchConnection fc = transport.openFetch()) {
  185.                 refs = fc.getRefs();
  186.                 if (refSpecs.isEmpty())
  187.                     for (Ref r : refs)
  188.                         refmap.put(r.getName(), r);
  189.                 else
  190.                     for (Ref r : refs)
  191.                         for (RefSpec rs : refSpecs)
  192.                             if (rs.matchSource(r)) {
  193.                                 refmap.put(r.getName(), r);
  194.                                 break;
  195.                             }
  196.                 return refmap;
  197.             }
  198.         } catch (URISyntaxException e) {
  199.             throw new InvalidRemoteException(MessageFormat.format(
  200.                     JGitText.get().invalidRemote, remote));
  201.         } catch (NotSupportedException e) {
  202.             throw new JGitInternalException(
  203.                     JGitText.get().exceptionCaughtDuringExecutionOfLsRemoteCommand,
  204.                     e);
  205.         } catch (TransportException e) {
  206.             throw new org.eclipse.jgit.api.errors.TransportException(
  207.                     e.getMessage(),
  208.                     e);
  209.         }
  210.     }

  211. }