blob: 6de2fef49fc8db948b8de1ce0a00ddcab2de5af1 [file] [log] [blame]
// 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;
}
}