// Copyright (C) 2011 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.google.gerrit.server.util; import com.google.gerrit.reviewdb.client.Branch; import com.google.gerrit.reviewdb.client.Project; import com.google.gerrit.reviewdb.client.SubmoduleSubscription; import com.google.gerrit.server.git.GitRepositoryManager; import org.eclipse.jgit.lib.BlobBasedConfig; import org.eclipse.jgit.lib.Constants; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; /** * It parses from a configuration file submodule sections. * <p> * Example of submodule sections: * * <pre> * [submodule "project-a"] * url = http://localhost/a * path = a * branch = . * * [submodule "project-b"] * url = http://localhost/b * path = b * branch = refs/heads/test * </pre> */ public class SubmoduleSectionParser { private final BlobBasedConfig bbc; private final String thisServer; private final Branch.NameKey superProjectBranch; private final GitRepositoryManager repoManager; public SubmoduleSectionParser(final BlobBasedConfig bbc, final String thisServer, final Branch.NameKey superProjectBranch, final GitRepositoryManager repoManager) { this.bbc = bbc; this.thisServer = thisServer; this.superProjectBranch = superProjectBranch; this.repoManager = repoManager; } public List<SubmoduleSubscription> parseAllSections() { List<SubmoduleSubscription> parsedSubscriptions = new ArrayList<>(); for (final String id : bbc.getSubsections("submodule")) { final SubmoduleSubscription subscription = parse(id); if (subscription != null) { parsedSubscriptions.add(subscription); } } return parsedSubscriptions; } private SubmoduleSubscription parse(final String id) { final String url = bbc.getString("submodule", id, "url"); final String path = bbc.getString("submodule", id, "path"); String branch = bbc.getString("submodule", id, "branch"); try { if (url != null && url.length() > 0 && path != null && path.length() > 0 && branch != null && branch.length() > 0) { // All required fields filled. boolean urlIsRelative = url.startsWith("../"); String server = null; if (!urlIsRelative) { // It is actually an URI. It could be ssh://localhost/project-a. server = new URI(url).getHost(); } if ((urlIsRelative) || (server != null && server.equalsIgnoreCase(thisServer))) { // Subscription really related to this running server. if (branch.equals(".")) { branch = superProjectBranch.get(); } else if (!branch.startsWith(Constants.R_REFS)) { branch = Constants.R_HEADS + branch; } final String urlExtractedPath = new URI(url).getPath(); String projectName; int fromIndex = urlExtractedPath.length() - 1; while (fromIndex > 0) { fromIndex = urlExtractedPath.lastIndexOf('/', fromIndex - 1); projectName = urlExtractedPath.substring(fromIndex + 1); if (projectName.endsWith(Constants.DOT_GIT_EXT)) { projectName = projectName.substring(0, // projectName.length() - Constants.DOT_GIT_EXT.length()); } if (repoManager.list().contains(new Project.NameKey(projectName))) { return new SubmoduleSubscription( superProjectBranch, new Branch.NameKey(new Project.NameKey(projectName), branch), path); } } } } } catch (URISyntaxException e) { // Error in url syntax (in fact it is uri syntax) } return null; } }