RepoProject.java

  1. /*
  2.  * Copyright (C) 2015, Google Inc. and others
  3.  *
  4.  * This program and the accompanying materials are made available under the
  5.  * terms of the Eclipse Distribution License v. 1.0 which is available at
  6.  * https://www.eclipse.org/org/documents/edl-v10.php.
  7.  *
  8.  * SPDX-License-Identifier: BSD-3-Clause
  9.  */
  10. package org.eclipse.jgit.gitrepo;

  11. import java.io.File;
  12. import java.io.FileInputStream;
  13. import java.io.FileOutputStream;
  14. import java.io.IOException;
  15. import java.nio.channels.FileChannel;
  16. import java.util.ArrayList;
  17. import java.util.Arrays;
  18. import java.util.Collection;
  19. import java.util.Collections;
  20. import java.util.HashSet;
  21. import java.util.List;
  22. import java.util.Set;

  23. import org.eclipse.jgit.lib.Repository;

  24. /**
  25.  * The representation of a repo sub project.
  26.  *
  27.  * @see <a href="https://code.google.com/p/git-repo/">git-repo project page</a>
  28.  * @since 4.0
  29.  */
  30. public class RepoProject implements Comparable<RepoProject> {
  31.     private final String name;
  32.     private final String path;
  33.     private final String revision;
  34.     private final String remote;
  35.     private final Set<String> groups;
  36.     private final List<CopyFile> copyfiles;
  37.     private final List<LinkFile> linkfiles;
  38.     private String recommendShallow;
  39.     private String url;
  40.     private String defaultRevision;

  41.     /**
  42.      * The representation of a reference file configuration.
  43.      *
  44.      * @since 4.8
  45.      */
  46.     public static class ReferenceFile {
  47.         final Repository repo;
  48.         final String path;
  49.         final String src;
  50.         final String dest;

  51.         /**
  52.          * @param repo
  53.          *            the super project.
  54.          * @param path
  55.          *            the path of the project containing this copyfile config.
  56.          * @param src
  57.          *            the source path relative to the sub repo.
  58.          * @param dest
  59.          *            the destination path relative to the super project.
  60.          */
  61.         public ReferenceFile(Repository repo, String path, String src, String dest) {
  62.             this.repo = repo;
  63.             this.path = path;
  64.             this.src = src;
  65.             this.dest = dest;
  66.         }
  67.     }

  68.     /**
  69.      * The representation of a copy file configuration.
  70.      */
  71.     public static class CopyFile extends ReferenceFile {
  72.         /**
  73.          * @param repo
  74.          *            the super project.
  75.          * @param path
  76.          *            the path of the project containing this copyfile config.
  77.          * @param src
  78.          *            the source path relative to the sub repo.
  79.          * @param dest
  80.          *            the destination path relative to the super project.
  81.          */
  82.         public CopyFile(Repository repo, String path, String src, String dest) {
  83.             super(repo, path, src, dest);
  84.         }

  85.         /**
  86.          * Do the copy file action.
  87.          *
  88.          * @throws IOException
  89.          */
  90.         public void copy() throws IOException {
  91.             File srcFile = new File(repo.getWorkTree(),
  92.                     path + "/" + src); //$NON-NLS-1$
  93.             File destFile = new File(repo.getWorkTree(), dest);
  94.             try (FileInputStream input = new FileInputStream(srcFile);
  95.                     FileOutputStream output = new FileOutputStream(destFile)) {
  96.                 FileChannel channel = input.getChannel();
  97.                 output.getChannel().transferFrom(channel, 0, channel.size());
  98.             }
  99.             destFile.setExecutable(srcFile.canExecute());
  100.         }
  101.     }

  102.     /**
  103.      * The representation of a link file configuration.
  104.      *
  105.      * @since 4.8
  106.      */
  107.     public static class LinkFile extends ReferenceFile {
  108.         /**
  109.          * @param repo
  110.          *            the super project.
  111.          * @param path
  112.          *            the path of the project containing this linkfile config.
  113.          * @param src
  114.          *            the source path relative to the sub repo.
  115.          * @param dest
  116.          *            the destination path relative to the super project.
  117.          */
  118.         public LinkFile(Repository repo, String path, String src, String dest) {
  119.             super(repo, path, src, dest);
  120.         }
  121.     }

  122.     /**
  123.      * Constructor for RepoProject
  124.      *
  125.      * @param name
  126.      *            the relative path to the {@code remote}
  127.      * @param path
  128.      *            the relative path to the super project
  129.      * @param revision
  130.      *            a SHA-1 or branch name or tag name
  131.      * @param remote
  132.      *            name of the remote definition
  133.      * @param groups
  134.      *            set of groups
  135.      * @param recommendShallow
  136.      *            recommendation for shallowness
  137.      * @since 4.4
  138.      */
  139.     public RepoProject(String name, String path, String revision,
  140.             String remote, Set<String> groups,
  141.             String recommendShallow) {
  142.         if (name == null) {
  143.             throw new NullPointerException();
  144.         }
  145.         this.name = name;
  146.         if (path != null)
  147.             this.path = path;
  148.         else
  149.             this.path = name;
  150.         this.revision = revision;
  151.         this.remote = remote;
  152.         this.groups = groups;
  153.         this.recommendShallow = recommendShallow;
  154.         copyfiles = new ArrayList<>();
  155.         linkfiles = new ArrayList<>();
  156.     }

  157.     /**
  158.      * Constructor for RepoProject
  159.      *
  160.      * @param name
  161.      *            the relative path to the {@code remote}
  162.      * @param path
  163.      *            the relative path to the super project
  164.      * @param revision
  165.      *            a SHA-1 or branch name or tag name
  166.      * @param remote
  167.      *            name of the remote definition
  168.      * @param groupsParam
  169.      *            comma separated group list
  170.      */
  171.     public RepoProject(String name, String path, String revision,
  172.             String remote, String groupsParam) {
  173.         this(name, path, revision, remote, new HashSet<String>(), null);
  174.         if (groupsParam != null && groupsParam.length() > 0)
  175.             this.setGroups(groupsParam);
  176.     }

  177.     /**
  178.      * Set the url of the sub repo.
  179.      *
  180.      * @param url
  181.      *            project url
  182.      * @return this for chaining.
  183.      */
  184.     public RepoProject setUrl(String url) {
  185.         this.url = url;
  186.         return this;
  187.     }

  188.     /**
  189.      * Set the url of the sub repo.
  190.      *
  191.      * @param groupsParam
  192.      *            comma separated group list
  193.      * @return this for chaining.
  194.      * @since 4.4
  195.      */
  196.     public RepoProject setGroups(String groupsParam) {
  197.         this.groups.clear();
  198.         this.groups.addAll(Arrays.asList(groupsParam.split(","))); //$NON-NLS-1$
  199.         return this;
  200.     }

  201.     /**
  202.      * Set the default revision for the sub repo.
  203.      *
  204.      * @param defaultRevision
  205.      *            the name of the default revision
  206.      * @return this for chaining.
  207.      */
  208.     public RepoProject setDefaultRevision(String defaultRevision) {
  209.         this.defaultRevision = defaultRevision;
  210.         return this;
  211.     }

  212.     /**
  213.      * Get the name (relative path to the {@code remote}) of this sub repo.
  214.      *
  215.      * @return {@code name}
  216.      */
  217.     public String getName() {
  218.         return name;
  219.     }

  220.     /**
  221.      * Get the path (relative path to the super project) of this sub repo.
  222.      *
  223.      * @return {@code path}
  224.      */
  225.     public String getPath() {
  226.         return path;
  227.     }

  228.     /**
  229.      * Get the revision of the sub repo.
  230.      *
  231.      * @return {@code revision} if set, or {@code defaultRevision}.
  232.      */
  233.     public String getRevision() {
  234.         return revision == null ? defaultRevision : revision;
  235.     }

  236.     /**
  237.      * Getter for the copyfile configurations.
  238.      *
  239.      * @return Immutable copy of {@code copyfiles}
  240.      */
  241.     public List<CopyFile> getCopyFiles() {
  242.         return Collections.unmodifiableList(copyfiles);
  243.     }

  244.     /**
  245.      * Getter for the linkfile configurations.
  246.      *
  247.      * @return Immutable copy of {@code linkfiles}
  248.      * @since 4.8
  249.      */
  250.     public List<LinkFile> getLinkFiles() {
  251.         return Collections.unmodifiableList(linkfiles);
  252.     }

  253.     /**
  254.      * Get the url of the sub repo.
  255.      *
  256.      * @return {@code url}
  257.      */
  258.     public String getUrl() {
  259.         return url;
  260.     }

  261.     /**
  262.      * Get the name of the remote definition of the sub repo.
  263.      *
  264.      * @return {@code remote}
  265.      */
  266.     public String getRemote() {
  267.         return remote;
  268.     }

  269.     /**
  270.      * Test whether this sub repo belongs to a specified group.
  271.      *
  272.      * @param group
  273.      *            a group
  274.      * @return true if {@code group} is present.
  275.      */
  276.     public boolean inGroup(String group) {
  277.         return groups.contains(group);
  278.     }

  279.     /**
  280.      * Return the set of groups.
  281.      *
  282.      * @return a Set of groups.
  283.      * @since 4.4
  284.      */
  285.     public Set<String> getGroups() {
  286.         return groups;
  287.     }

  288.     /**
  289.      * Return the recommendation for shallowness.
  290.      *
  291.      * @return the String of "clone-depth"
  292.      * @since 4.4
  293.      */
  294.     public String getRecommendShallow() {
  295.         return recommendShallow;
  296.     }

  297.     /**
  298.      * Sets the recommendation for shallowness.
  299.      *
  300.      * @param recommendShallow
  301.      *            recommendation for shallowness
  302.      * @since 4.4
  303.      */
  304.     public void setRecommendShallow(String recommendShallow) {
  305.         this.recommendShallow = recommendShallow;
  306.     }

  307.     /**
  308.      * Add a copy file configuration.
  309.      *
  310.      * @param copyfile a {@link org.eclipse.jgit.gitrepo.RepoProject.CopyFile} object.
  311.      */
  312.     public void addCopyFile(CopyFile copyfile) {
  313.         copyfiles.add(copyfile);
  314.     }

  315.     /**
  316.      * Add a bunch of copyfile configurations.
  317.      *
  318.      * @param copyFiles
  319.      *            a collection of
  320.      *            {@link org.eclipse.jgit.gitrepo.RepoProject.CopyFile} objects
  321.      */
  322.     public void addCopyFiles(Collection<CopyFile> copyFiles) {
  323.         this.copyfiles.addAll(copyFiles);
  324.     }

  325.     /**
  326.      * Clear all the copyfiles.
  327.      *
  328.      * @since 4.2
  329.      */
  330.     public void clearCopyFiles() {
  331.         this.copyfiles.clear();
  332.     }

  333.     /**
  334.      * Add a link file configuration.
  335.      *
  336.      * @param linkfile a {@link org.eclipse.jgit.gitrepo.RepoProject.LinkFile} object.
  337.      * @since 4.8
  338.      */
  339.     public void addLinkFile(LinkFile linkfile) {
  340.         linkfiles.add(linkfile);
  341.     }

  342.     /**
  343.      * Add a bunch of linkfile configurations.
  344.      *
  345.      * @param linkFiles
  346.      *            a collection of {@link LinkFile}s
  347.      * @since 4.8
  348.      */
  349.     public void addLinkFiles(Collection<LinkFile> linkFiles) {
  350.         this.linkfiles.addAll(linkFiles);
  351.     }

  352.     /**
  353.      * Clear all the linkfiles.
  354.      *
  355.      * @since 4.8
  356.      */
  357.     public void clearLinkFiles() {
  358.         this.linkfiles.clear();
  359.     }

  360.     private String getPathWithSlash() {
  361.         if (path.endsWith("/")) { //$NON-NLS-1$
  362.             return path;
  363.         }
  364.         return path + "/"; //$NON-NLS-1$
  365.     }

  366.     /**
  367.      * Check if this sub repo is the ancestor of given sub repo.
  368.      *
  369.      * @param that
  370.      *            non null
  371.      * @return true if this sub repo is the ancestor of given sub repo.
  372.      */
  373.     public boolean isAncestorOf(RepoProject that) {
  374.         return isAncestorOf(that.getPathWithSlash());
  375.     }

  376.     /**
  377.      * Check if this sub repo is an ancestor of the given path.
  378.      *
  379.      * @param thatPath
  380.      *            path to be checked to see if it is within this repository
  381.      * @return true if this sub repo is an ancestor of the given path.
  382.      * @since 4.2
  383.      */
  384.     public boolean isAncestorOf(String thatPath) {
  385.         return thatPath.startsWith(getPathWithSlash());
  386.     }

  387.     /** {@inheritDoc} */
  388.     @Override
  389.     public boolean equals(Object o) {
  390.         if (o instanceof RepoProject) {
  391.             RepoProject that = (RepoProject) o;
  392.             return this.getPathWithSlash().equals(that.getPathWithSlash());
  393.         }
  394.         return false;
  395.     }

  396.     /** {@inheritDoc} */
  397.     @Override
  398.     public int hashCode() {
  399.         return this.getPathWithSlash().hashCode();
  400.     }

  401.     /** {@inheritDoc} */
  402.     @Override
  403.     public int compareTo(RepoProject that) {
  404.         return this.getPathWithSlash().compareTo(that.getPathWithSlash());
  405.     }
  406. }