| // 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 java.net.URI; |
| import java.net.URISyntaxException; |
| import java.util.HashSet; |
| import java.util.Set; |
| import org.eclipse.jgit.lib.Config; |
| import org.eclipse.jgit.lib.Constants; |
| |
| /** |
| * 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 Config bbc; |
| private final String canonicalWebUrl; |
| private final Branch.NameKey superProjectBranch; |
| |
| public SubmoduleSectionParser( |
| Config bbc, String canonicalWebUrl, Branch.NameKey superProjectBranch) { |
| this.bbc = bbc; |
| this.canonicalWebUrl = canonicalWebUrl; |
| this.superProjectBranch = superProjectBranch; |
| } |
| |
| public Set<SubmoduleSubscription> parseAllSections() { |
| Set<SubmoduleSubscription> parsedSubscriptions = new HashSet<>(); |
| for (String id : bbc.getSubsections("submodule")) { |
| final SubmoduleSubscription subscription = parse(id); |
| if (subscription != null) { |
| parsedSubscriptions.add(subscription); |
| } |
| } |
| return parsedSubscriptions; |
| } |
| |
| private SubmoduleSubscription parse(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. |
| String project; |
| |
| if (branch.equals(".")) { |
| branch = superProjectBranch.get(); |
| } |
| |
| // relative URL |
| if (url.startsWith("../")) { |
| // prefix with a slash for easier relative path walks |
| project = '/' + superProjectBranch.getParentKey().get(); |
| String hostPart = url; |
| while (hostPart.startsWith("../")) { |
| int lastSlash = project.lastIndexOf('/'); |
| if (lastSlash < 0) { |
| // too many levels up, ignore for now |
| return null; |
| } |
| project = project.substring(0, lastSlash); |
| hostPart = hostPart.substring(3); |
| } |
| project = project + "/" + hostPart; |
| |
| // remove leading '/' |
| project = project.substring(1); |
| } else { |
| // It is actually an URI. It could be ssh://localhost/project-a. |
| URI targetServerURI = new URI(url); |
| URI thisServerURI = new URI(canonicalWebUrl); |
| String thisHost = thisServerURI.getHost(); |
| String targetHost = targetServerURI.getHost(); |
| if (thisHost == null || targetHost == null || !targetHost.equalsIgnoreCase(thisHost)) { |
| return null; |
| } |
| String p1 = targetServerURI.getPath(); |
| String p2 = thisServerURI.getPath(); |
| if (!p1.startsWith(p2)) { |
| // When we are running the server at |
| // http://server/my-gerrit/ but the subscription is for |
| // http://server/other-teams-gerrit/ |
| return null; |
| } |
| // skip common part |
| project = p1.substring(p2.length()); |
| } |
| |
| while (project.startsWith("/")) { |
| project = project.substring(1); |
| } |
| |
| if (project.endsWith(Constants.DOT_GIT_EXT)) { |
| project = |
| project.substring( |
| 0, // |
| project.length() - Constants.DOT_GIT_EXT.length()); |
| } |
| Project.NameKey projectKey = new Project.NameKey(project); |
| return new SubmoduleSubscription( |
| superProjectBranch, new Branch.NameKey(projectKey, branch), path); |
| } |
| } catch (URISyntaxException e) { |
| // Error in url syntax (in fact it is uri syntax) |
| } |
| return null; |
| } |
| } |