| // Copyright (C) 2021 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.task; |
| |
| import com.google.auto.value.AutoValue; |
| import com.google.common.base.Preconditions; |
| import com.google.gerrit.entities.AccountGroup; |
| import com.google.gerrit.entities.BranchNameKey; |
| import com.google.gerrit.entities.RefNames; |
| import com.google.gerrit.server.account.AccountCache; |
| import com.google.gerrit.server.account.GroupCache; |
| import com.google.gerrit.server.config.AllProjectsName; |
| import com.google.gerrit.server.config.AllUsersName; |
| import java.nio.file.Path; |
| import java.nio.file.Paths; |
| import org.eclipse.jgit.errors.ConfigInvalidException; |
| |
| /** An immutable reference to a task in task config file. */ |
| @AutoValue |
| public abstract class TaskKey { |
| protected static final String CONFIG_SECTION = "task"; |
| protected static final String CONFIG_TASKS_FACTORY = "tasks-factory"; |
| |
| /** Creates a TaskKey with task name as the name of sub section. */ |
| public static TaskKey create(SubSectionKey section) { |
| return create(section, section.subSection()); |
| } |
| |
| /** Creates a TaskKey with given FileKey and task name and sub section's name as 'task'. */ |
| public static TaskKey create(FileKey file, String task) { |
| return create(SubSectionKey.create(file, CONFIG_SECTION, task)); |
| } |
| |
| /** Creates a TaskKey from a sub section and task name, generally used by TasksFactory. */ |
| public static TaskKey create(SubSectionKey section, String task) { |
| return new AutoValue_TaskKey(section, task); |
| } |
| |
| public BranchNameKey branch() { |
| return subSection().file().branch(); |
| } |
| |
| public abstract SubSectionKey subSection(); |
| |
| public abstract String task(); |
| |
| public boolean isTasksFactoryGenerated() { |
| return subSection().section().equals(CONFIG_TASKS_FACTORY); |
| } |
| |
| public static class Builder { |
| protected final AccountCache accountCache; |
| protected final AllProjectsName allProjectsName; |
| protected final AllUsersName allUsersName; |
| protected final FileKey relativeTo; |
| protected BranchNameKey branch; |
| protected String file; |
| protected String task; |
| protected GroupCache groupCache; |
| protected TaskPluginConfiguration config; |
| |
| Builder( |
| FileKey relativeTo, |
| AllProjectsName allProjectsName, |
| AllUsersName allUsersName, |
| AccountCache accountCache, |
| GroupCache groupCache, |
| TaskPluginConfiguration config) { |
| this.relativeTo = relativeTo; |
| this.allProjectsName = allProjectsName; |
| this.allUsersName = allUsersName; |
| this.accountCache = accountCache; |
| this.groupCache = groupCache; |
| this.config = config; |
| } |
| |
| public TaskKey buildTaskKey() { |
| return isReferencingAnotherRef() ? getAnotherRefTask() : getSameRefTask(); |
| } |
| |
| protected TaskKey getAnotherRefTask() { |
| return TaskKey.create( |
| isReferencingRootFile() |
| ? FileKey.create(branch, TaskFileConstants.TASK_CFG) |
| : FileKey.create(branch, file), |
| task); |
| } |
| |
| protected TaskKey getSameRefTask() { |
| return TaskKey.create( |
| isRelativePath() ? relativeTo : FileKey.create(relativeTo.branch(), file), task); |
| } |
| |
| public void setAbsolute() { |
| file = TaskFileConstants.TASK_DIR; |
| } |
| |
| public void setPath(Path path) throws ConfigInvalidException { |
| Path parentDir = Paths.get(relativeTo.file()).getParent(); |
| if (parentDir == null) { |
| parentDir = Paths.get(TaskFileConstants.TASK_DIR); |
| } |
| |
| file = |
| isRelativePath() |
| ? parentDir.resolve(path).toString() |
| : Paths.get(file).resolve(path).toString(); |
| throwIfInvalidPath(); |
| } |
| |
| public void setRefRootFile() throws ConfigInvalidException { |
| Preconditions.checkState(!isFileAlreadySet()); |
| file = TaskFileConstants.TASK_CFG; |
| } |
| |
| public void setTaskName(String task) { |
| this.task = task; |
| } |
| |
| public void setUsername(String username) throws ConfigInvalidException { |
| branch = |
| BranchNameKey.create( |
| allUsersName, |
| RefNames.refsUsers( |
| accountCache |
| .getByUsername(username) |
| .orElseThrow( |
| () -> new ConfigInvalidException("Cannot resolve username: " + username)) |
| .account() |
| .id())); |
| } |
| |
| public void setGroupName(String groupName) throws ConfigInvalidException { |
| branch = |
| BranchNameKey.create( |
| allUsersName, |
| RefNames.refsGroups( |
| groupCache |
| .get(AccountGroup.nameKey(groupName)) |
| .orElseThrow( |
| () -> |
| new ConfigInvalidException( |
| String.format("Cannot resolve group name: %s", groupName))) |
| .getGroupUUID())); |
| } |
| |
| public void setGroupUUID(String uuid) throws ConfigInvalidException { |
| branch = |
| BranchNameKey.create( |
| allUsersName, |
| RefNames.refsGroups( |
| groupCache |
| .get(AccountGroup.uuid(uuid)) |
| .orElseThrow( |
| () -> |
| new ConfigInvalidException( |
| String.format("Cannot resolve group uuid: %s", uuid))) |
| .getGroupUUID())); |
| } |
| |
| public void setReferringRootConfigBranchTask() { |
| branch = config.getRootConfigBranch(); |
| } |
| |
| protected void throwIfInvalidPath() throws ConfigInvalidException { |
| Path path = Paths.get(file); |
| if (!path.startsWith(TaskFileConstants.TASK_DIR) |
| && !path.equals(Paths.get(TaskFileConstants.TASK_CFG))) { |
| throw new ConfigInvalidException( |
| "Invalid config location, path should be " |
| + TaskFileConstants.TASK_CFG |
| + " or under " |
| + TaskFileConstants.TASK_DIR |
| + " directory"); |
| } |
| } |
| |
| /** Returns true when the path implies relative or same file. */ |
| protected boolean isRelativePath() { |
| return file == null; |
| } |
| |
| protected boolean isFileAlreadySet() { |
| return file != null; |
| } |
| |
| protected boolean isReferencingRootFile() { |
| return file == null; |
| } |
| |
| protected boolean isReferencingAnotherRef() { |
| return branch != null; |
| } |
| } |
| } |