blob: 74d3efb222ee5eaa9fd417be61e2fd06a8e70ba9 [file] [log] [blame]
// Copyright (C) 2015 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.importer;
import static java.lang.String.format;
import com.google.gerrit.extensions.annotations.PluginData;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.restapi.AcceptsCreate;
import com.google.gerrit.extensions.restapi.ChildCollection;
import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.RestView;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.config.ConfigResource;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
@Singleton
@RequiresCapability(ImportCapability.ID)
public class ProjectsCollection implements
ChildCollection<ConfigResource, ImportProjectResource>,
AcceptsCreate<ConfigResource> {
class FileSystemLayout {
private String SUFFIX_IMPORT_STATUS_FILE = ".$importstatus";
public File getLockRoot() {
return lockRoot;
}
File getImportStatusFile(String id) {
return new File(lockRoot, format("%s%s", id, SUFFIX_IMPORT_STATUS_FILE));
}
String resolveProjectName(File f) throws IOException {
if(! f.isFile()) {
throw new RuntimeException(format("'%s' is not a file. Project names"
+ "can only be resolved for existing files, not for directories."
, f));
}
if(! f.getName().endsWith(SUFFIX_IMPORT_STATUS_FILE)) {
throw new RuntimeException(format("'%s' is not a valid import status"
+ "file. Invalid appendix. Should be '%s'.", f,
SUFFIX_IMPORT_STATUS_FILE));
}
String diff = diff(lockRoot, f);
return diff.substring(0, diff.length() -
SUFFIX_IMPORT_STATUS_FILE.length());
}
/**
* Returns the path between two file instances. The child instance
* is expected to be a child of the parent instance.
* @param parent
* @param child
* @return The path between parent and child.
* @throws IOException in case <code>child</code> is not a child of
* <code>parent</code>.
*/
private String diff(File parent, File child) throws IOException {
Path parentPath = parent.getAbsoluteFile().toPath();
Path childPath= child.getAbsoluteFile().toPath();
if (childPath.startsWith(parentPath)) {
return parentPath.relativize(childPath).toString();
}
throw new IOException(String.format("'%s' is not a child of '%s'.",
child, parent));
}
}
public final FileSystemLayout FS_LAYOUT = new FileSystemLayout();
private final DynamicMap<RestView<ImportProjectResource>> views;
private final ImportProject.Factory importProjectFactory;
private final Provider<ListImportedProjects> list;
private final File lockRoot;
@Inject
ProjectsCollection(
DynamicMap<RestView<ImportProjectResource>> views,
ImportProject.Factory importProjectFactory,
Provider<ListImportedProjects> list,
@PluginData File data) {
this.views = views;
this.importProjectFactory = importProjectFactory;
this.list = list;
this.lockRoot = data;
}
@Override
public RestView<ConfigResource> list() {
return list.get();
}
@Override
public ImportProjectResource parse(ConfigResource parent, IdString id)
throws ResourceNotFoundException {
return parse(id.get());
}
public ImportProjectResource parse(String id)
throws ResourceNotFoundException {
File f = FS_LAYOUT.getImportStatusFile(id);
if (!f.exists()) {
throw new ResourceNotFoundException(id);
}
return new ImportProjectResource(id, f);
}
@Override
public DynamicMap<RestView<ImportProjectResource>> views() {
return views;
}
@Override
@SuppressWarnings("unchecked")
public ImportProject create(ConfigResource parent, IdString id)
throws RestApiException {
return importProjectFactory.create(new Project.NameKey(id.get()));
}
}