Java tutorial
// Copyright (C) 2017 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.googlesource.gerrit.plugins.supermanifest; import static com.google.common.base.Strings.nullToEmpty; import static com.google.gerrit.reviewdb.client.RefNames.REFS_HEADS; import com.google.gerrit.reviewdb.client.Project; import java.net.URI; import java.net.URISyntaxException; import java.util.Objects; import org.eclipse.jgit.errors.ConfigInvalidException; import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.Repository; class ConfigEntry { public static final String SECTION_NAME = "superproject"; Project.NameKey srcRepoKey; String srcRef; URI baseUri; ToolType toolType; String xmlPath; Project.NameKey destRepoKey; String repoGroups; boolean recordSubmoduleLabels; boolean ignoreRemoteFailures; // destBranch can be "*" in which case srcRef is ignored. String destBranch; ConfigEntry(Config cfg, String name) throws ConfigInvalidException { String[] parts = name.split(":"); if (parts.length != 2) { throw new ConfigInvalidException(String.format("pluginName '%s' must have form REPO:BRANCH", name)); } String destRepo = parts[0]; String destRef = parts[1]; if (!destRef.startsWith(REFS_HEADS)) { throw new ConfigInvalidException( String.format("invalid destination '%s'. Must specify refs/heads/", destRef)); } if (destRef.contains("*") && !destRef.equals(REFS_HEADS + "*")) { throw new ConfigInvalidException( String.format("invalid destination '%s'. Use just '*' for all branches.", destRef)); } String srcRepo = cfg.getString(SECTION_NAME, name, "srcRepo"); if (srcRepo == null) { throw new ConfigInvalidException(String.format("entry %s did not specify srcRepo", name)); } // TODO(hanwen): sanity check repo names. srcRepoKey = new Project.NameKey(srcRepo); String toolType = nullToEmpty(cfg.getString(SECTION_NAME, name, "toolType")); switch (toolType) { case "": case "repo": this.toolType = ToolType.Repo; break; case "jiri": this.toolType = ToolType.Jiri; break; default: throw new ConfigInvalidException(String.format("entry %s has invalid toolType: %s", name, toolType)); } if (destRef.equals(REFS_HEADS + "*")) { srcRef = ""; } else { if (!Repository.isValidRefName(destRef)) { throw new ConfigInvalidException(String.format("destination branch '%s' invalid", destRef)); } srcRef = cfg.getString(SECTION_NAME, name, "srcRef"); if (!Repository.isValidRefName(srcRef)) { throw new ConfigInvalidException(String.format("source ref '%s' invalid", srcRef)); } if (srcRef == null) { throw new ConfigInvalidException(String.format("entry %s did not specify srcRef", name)); } } xmlPath = cfg.getString(SECTION_NAME, name, "srcPath"); if (xmlPath == null) { throw new ConfigInvalidException(String.format("entry %s did not specify srcPath", name)); } destRepoKey = new Project.NameKey(destRepo); // The external format is chosen so we can support copying over tags as well. destBranch = destRef.substring(REFS_HEADS.length()); repoGroups = nullToEmpty(cfg.getString(SECTION_NAME, name, "groups")); recordSubmoduleLabels = cfg.getBoolean(SECTION_NAME, name, "recordSubmoduleLabels", false); ignoreRemoteFailures = cfg.getBoolean(SECTION_NAME, name, "ignoreRemoteFailures", false); try { // http://foo/platform/manifest => http://foo/platform/ baseUri = new URI(srcRepoKey.toString()).resolve(""); } catch (URISyntaxException exception) { throw new ConfigInvalidException("could not build src URL", exception); } } public String src() { String src = srcRef; if (destBranch.equals("*")) { src = "*"; } return srcRepoKey + ":" + src + ":" + xmlPath; } public String dest() { return destRepoKey + ":" + destBranch; } @Override public String toString() { return String.format("%s (%s) => %s", src(), toolType, dest()); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ConfigEntry that = (ConfigEntry) o; if (!destRepoKey.equals(that.destRepoKey)) return false; return destBranch.equals(that.destBranch); } @Override public int hashCode() { return Objects.hash(destRepoKey, destBranch); } /** @return the srcRepoKey */ public Project.NameKey getSrcRepoKey() { return srcRepoKey; } /** @return the srcRef */ public String getSrcRef() { return srcRef; } /** @return the baseUri */ public URI getBaseUri() { return baseUri; } /** @return the toolType */ public ToolType getToolType() { return toolType; } /** @return the xmlPath */ public String getXmlPath() { return xmlPath; } /** @return the destRepoKey */ public Project.NameKey getDestRepoKey() { return destRepoKey; } /** @return the recordSubmoduleLabels */ public boolean isRecordSubmoduleLabels() { return recordSubmoduleLabels; } /** @return group restriction suitable for passing to {@code repo init -g} */ public String getGroupsParameter() { return repoGroups; } /** @return the destBranch */ public String getDestBranch() { return destBranch; } enum ToolType { Repo, Jiri } }