| // Copyright (C) 2013 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.config; | |
| import static com.google.gerrit.server.project.ProjectCache.noSuchProject; | |
| import com.google.gerrit.entities.Project; | |
| import com.google.gerrit.server.plugins.Plugin; | |
| import com.google.gerrit.server.plugins.ReloadPluginListener; | |
| import com.google.gerrit.server.project.NoSuchProjectException; | |
| import com.google.gerrit.server.project.ProjectCache; | |
| import com.google.gerrit.server.project.ProjectLevelConfig; | |
| import com.google.gerrit.server.project.ProjectState; | |
| import com.google.gerrit.server.securestore.SecureStore; | |
| import com.google.inject.Inject; | |
| import com.google.inject.Provider; | |
| import com.google.inject.Singleton; | |
| import java.util.HashMap; | |
| import java.util.Map; | |
| import org.eclipse.jgit.lib.Config; | |
| @Singleton | |
| public class PluginConfigFactory implements ReloadPluginListener { | |
| private static final String EXTENSION = ".config"; | |
| private final GlobalPluginConfigProvider globalPluginConfigProvider; | |
| private final Provider<Config> cfgProvider; | |
| private final ProjectCache projectCache; | |
| private final ProjectState.Factory projectStateFactory; | |
| private final SecureStore secureStore; | |
| private final Map<String, Config> pluginConfigs; | |
| private volatile Config cfg; | |
| @Inject | |
| PluginConfigFactory( | |
| @GerritServerConfig Provider<Config> cfgProvider, | |
| GlobalPluginConfigProvider globalPluginConfigProvider, | |
| ProjectCache projectCache, | |
| ProjectState.Factory projectStateFactory, | |
| SecureStore secureStore) { | |
| this.globalPluginConfigProvider = globalPluginConfigProvider; | |
| this.cfgProvider = cfgProvider; | |
| this.projectCache = projectCache; | |
| this.projectStateFactory = projectStateFactory; | |
| this.secureStore = secureStore; | |
| this.pluginConfigs = new HashMap<>(); | |
| this.cfg = cfgProvider.get(); | |
| } | |
| /** | |
| * Returns the configuration for the specified plugin that is stored in the 'gerrit.config' file. | |
| * | |
| * <p>The returned plugin configuration provides access to all parameters of the 'gerrit.config' | |
| * file that are set in the 'plugin' subsection of the specified plugin. | |
| * | |
| * <p>E.g.: [plugin "my-plugin"] myKey = myValue | |
| * | |
| * @param pluginName the name of the plugin for which the configuration should be returned | |
| * @return the plugin configuration from the 'gerrit.config' file | |
| */ | |
| public PluginConfig getFromGerritConfig(String pluginName) { | |
| return getFromGerritConfig(pluginName, false); | |
| } | |
| /** | |
| * Returns the configuration for the specified plugin that is stored in the 'gerrit.config' file. | |
| * | |
| * <p>The returned plugin configuration provides access to all parameters of the 'gerrit.config' | |
| * file that are set in the 'plugin' subsection of the specified plugin. | |
| * | |
| * <p>E.g.: [plugin "my-plugin"] myKey = myValue | |
| * | |
| * @param pluginName the name of the plugin for which the configuration should be returned | |
| * @param refresh if <code>true</code> it is checked if the 'gerrit.config' file was modified and | |
| * if yes the Gerrit configuration is reloaded, if <code>false</code> the cached Gerrit | |
| * configuration is used | |
| * @return the plugin configuration from the 'gerrit.config' file | |
| */ | |
| public PluginConfig getFromGerritConfig(String pluginName, boolean refresh) { | |
| if (refresh) { | |
| if (secureStore.isOutdated()) { | |
| secureStore.reload(); | |
| } | |
| cfg = cfgProvider.get(); | |
| } | |
| return PluginConfig.createFromGerritConfig(pluginName, cfg); | |
| } | |
| /** | |
| * Returns the configuration for the specified plugin that is stored in the 'project.config' file | |
| * of the specified project. | |
| * | |
| * <p>The returned plugin configuration provides access to all parameters of the 'project.config' | |
| * file that are set in the 'plugin' subsection of the specified plugin. | |
| * | |
| * <p>E.g.: [plugin "my-plugin"] myKey = myValue | |
| * | |
| * @param projectName the name of the project for which the plugin configuration should be | |
| * returned | |
| * @param pluginName the name of the plugin for which the configuration should be returned | |
| * @return the plugin configuration from the 'project.config' file of the specified project | |
| * @throws NoSuchProjectException thrown if the specified project does not exist | |
| */ | |
| public PluginConfig getFromProjectConfig(Project.NameKey projectName, String pluginName) | |
| throws NoSuchProjectException { | |
| ProjectState projectState = | |
| projectCache.get(projectName).orElseThrow(noSuchProject(projectName)); | |
| return getFromProjectConfig(projectState, pluginName); | |
| } | |
| /** | |
| * Returns the configuration for the specified plugin that is stored in the 'project.config' file | |
| * of the specified project. | |
| * | |
| * <p>The returned plugin configuration provides access to all parameters of the 'project.config' | |
| * file that are set in the 'plugin' subsection of the specified plugin. | |
| * | |
| * <p>E.g.: [plugin "my-plugin"] myKey = myValue | |
| * | |
| * @param projectState the project for which the plugin configuration should be returned | |
| * @param pluginName the name of the plugin for which the configuration should be returned | |
| * @return the plugin configuration from the 'project.config' file of the specified project | |
| */ | |
| public PluginConfig getFromProjectConfig(ProjectState projectState, String pluginName) { | |
| return projectState.getPluginConfig(pluginName); | |
| } | |
| /** | |
| * Returns the configuration for the specified plugin that is stored in the 'project.config' file | |
| * of the specified project. Parameters which are not set in the 'project.config' of this project | |
| * are inherited from the parent project's 'project.config' files. | |
| * | |
| * <p>The returned plugin configuration provides access to all parameters of the 'project.config' | |
| * file that are set in the 'plugin' subsection of the specified plugin. | |
| * | |
| * <p>E.g.: child project: [plugin "my-plugin"] myKey = childValue | |
| * | |
| * <p>parent project: [plugin "my-plugin"] myKey = parentValue anotherKey = someValue | |
| * | |
| * <p>return: [plugin "my-plugin"] myKey = childValue anotherKey = someValue | |
| * | |
| * @param projectName the name of the project for which the plugin configuration should be | |
| * returned | |
| * @param pluginName the name of the plugin for which the configuration should be returned | |
| * @return the plugin configuration from the 'project.config' file of the specified project with | |
| * inherited non-set parameters from the parent projects | |
| * @throws NoSuchProjectException thrown if the specified project does not exist | |
| */ | |
| public PluginConfig getFromProjectConfigWithInheritance( | |
| Project.NameKey projectName, String pluginName) throws NoSuchProjectException { | |
| return getFromProjectConfig(projectName, pluginName).withInheritance(projectStateFactory); | |
| } | |
| /** | |
| * Returns the configuration for the specified plugin that is stored in the 'project.config' file | |
| * of the specified project. Parameters which are not set in the 'project.config' of this project | |
| * are inherited from the parent project's 'project.config' files. | |
| * | |
| * <p>The returned plugin configuration provides access to all parameters of the 'project.config' | |
| * file that are set in the 'plugin' subsection of the specified plugin. | |
| * | |
| * <p>E.g.: child project: [plugin "my-plugin"] myKey = childValue | |
| * | |
| * <p>parent project: [plugin "my-plugin"] myKey = parentValue anotherKey = someValue | |
| * | |
| * <p>return: [plugin "my-plugin"] myKey = childValue anotherKey = someValue | |
| * | |
| * @param projectState the project for which the plugin configuration should be returned | |
| * @param pluginName the name of the plugin for which the configuration should be returned | |
| * @return the plugin configuration from the 'project.config' file of the specified project with | |
| * inherited non-set parameters from the parent projects | |
| */ | |
| public PluginConfig getFromProjectConfigWithInheritance( | |
| ProjectState projectState, String pluginName) { | |
| return getFromProjectConfig(projectState, pluginName).withInheritance(projectStateFactory); | |
| } | |
| /** | |
| * Returns the configuration for the specified plugin that is stored in the plugin configuration | |
| * file '{@code etc/<plugin-name>.config}'. | |
| * | |
| * <p>The plugin configuration is only loaded once and is then cached. | |
| * | |
| * @param pluginName the name of the plugin for which the configuration should be returned | |
| * @return the plugin configuration from the '{@code etc/<plugin-name>.config}' file | |
| */ | |
| public synchronized Config getGlobalPluginConfig(String pluginName) { | |
| if (pluginConfigs.containsKey(pluginName)) { | |
| return pluginConfigs.get(pluginName); | |
| } | |
| Config cfg = globalPluginConfigProvider.get(pluginName); | |
| GlobalPluginConfig pluginConfig = new GlobalPluginConfig(pluginName, cfg, secureStore); | |
| pluginConfigs.put(pluginName, pluginConfig); | |
| return pluginConfig; | |
| } | |
| /** | |
| * Returns the configuration for the specified plugin that is stored in the '{@code | |
| * <plugin-name>.config}' file in the 'refs/meta/config' branch of the specified project. | |
| * | |
| * @param projectName the name of the project for which the plugin configuration should be | |
| * returned | |
| * @param pluginName the name of the plugin for which the configuration should be returned | |
| * @return the plugin configuration from the '{@code <plugin-name>.config}' file of the specified | |
| * project | |
| * @throws NoSuchProjectException thrown if the specified project does not exist | |
| */ | |
| public Config getProjectPluginConfig(Project.NameKey projectName, String pluginName) | |
| throws NoSuchProjectException { | |
| return getPluginConfig(projectName, pluginName).get(); | |
| } | |
| /** | |
| * Returns the configuration for the specified plugin that is stored in the '{@code | |
| * <plugin-name>.config}' file in the 'refs/meta/config' branch of the specified project. | |
| * | |
| * @param projectState the project for which the plugin configuration should be returned | |
| * @param pluginName the name of the plugin for which the configuration should be returned | |
| * @return the plugin configuration from the '{@code <plugin-name>.config}' file of the specified | |
| * project | |
| */ | |
| public Config getProjectPluginConfig(ProjectState projectState, String pluginName) { | |
| return projectState.getConfig(pluginName + EXTENSION).get(); | |
| } | |
| /** | |
| * Returns the configuration for the specified plugin that is stored in the '{@code | |
| * <plugin-name>.config}' file in the 'refs/meta/config' branch of the specified project. | |
| * Parameters which are not set in the '{@code <plugin-name>.config}' of this project are | |
| * inherited from the parent project's '{@code <plugin-name>.config}' files. | |
| * | |
| * <p>E.g.: child project: [mySection "mySubsection"] myKey = childValue | |
| * | |
| * <p>parent project: [mySection "mySubsection"] myKey = parentValue anotherKey = someValue | |
| * | |
| * <p>return: [mySection "mySubsection"] myKey = childValue anotherKey = someValue | |
| * | |
| * @param projectName the name of the project for which the plugin configuration should be | |
| * returned | |
| * @param pluginName the name of the plugin for which the configuration should be returned | |
| * @return the plugin configuration from the '{@code <plugin-name>.config}' file of the specified | |
| * project with inheriting non-set parameters from the parent projects | |
| * @throws NoSuchProjectException thrown if the specified project does not exist | |
| */ | |
| public Config getProjectPluginConfigWithInheritance( | |
| Project.NameKey projectName, String pluginName) throws NoSuchProjectException { | |
| return getPluginConfig(projectName, pluginName).getWithInheritance(/* merge= */ false); | |
| } | |
| /** | |
| * Returns the configuration for the specified plugin that is stored in the '{@code | |
| * <plugin-name>.config}' file in the 'refs/meta/config' branch of the specified project. | |
| * Parameters which are not set in the '{@code <plugin-name>.config}' of this project are | |
| * inherited from the parent project's '{@code <plugin-name>.config}' files. | |
| * | |
| * <p>E.g.: child project: [mySection "mySubsection"] myKey = childValue | |
| * | |
| * <p>parent project: [mySection "mySubsection"] myKey = parentValue anotherKey = someValue | |
| * | |
| * <p>return: [mySection "mySubsection"] myKey = childValue anotherKey = someValue | |
| * | |
| * @param projectState the project for which the plugin configuration should be returned | |
| * @param pluginName the name of the plugin for which the configuration should be returned | |
| * @return the plugin configuration from the '{@code <plugin-name>.config}' file of the specified | |
| * project with inheriting non-set parameters from the parent projects | |
| */ | |
| public Config getProjectPluginConfigWithInheritance( | |
| ProjectState projectState, String pluginName) { | |
| return projectState.getConfig(pluginName + EXTENSION).getWithInheritance(/* merge= */ false); | |
| } | |
| /** | |
| * Returns the configuration for the specified plugin that is stored in the '{@code | |
| * <plugin-name>.config}' file in the 'refs/meta/config' branch of the specified project. | |
| * Parameters from the '{@code <plugin-name>.config}' of the parent project are appended to this | |
| * project's '{@code <plugin-name>.config}' files. | |
| * | |
| * <p>E.g.: child project: [mySection "mySubsection"] myKey = childValue | |
| * | |
| * <p>parent project: [mySection "mySubsection"] myKey = parentValue anotherKey = someValue | |
| * | |
| * <p>return: [mySection "mySubsection"] myKey = childValue myKey = parentValue anotherKey = | |
| * someValue | |
| * | |
| * @param projectName the name of the project for which the plugin configuration should be | |
| * returned | |
| * @param pluginName the name of the plugin for which the configuration should be returned | |
| * @return the plugin configuration from the '{@code <plugin-name>.config}' file of the specified | |
| * project with parameters from the parent projects appended to the project values | |
| * @throws NoSuchProjectException thrown if the specified project does not exist | |
| */ | |
| public Config getProjectPluginConfigWithMergedInheritance( | |
| Project.NameKey projectName, String pluginName) throws NoSuchProjectException { | |
| return getPluginConfig(projectName, pluginName).getWithInheritance(/* merge= */ true); | |
| } | |
| /** | |
| * Returns the configuration for the specified plugin that is stored in the '{@code | |
| * <plugin-name>.config}' file in the 'refs/meta/config' branch of the specified project. | |
| * Parameters from the '{@code <plugin-name>.config}' of the parent project are appended to this | |
| * project's '{@code <plugin-name>.config}' files. | |
| * | |
| * <p>E.g.: child project: [mySection "mySubsection"] myKey = childValue | |
| * | |
| * <p>parent project: [mySection "mySubsection"] myKey = parentValue anotherKey = someValue | |
| * | |
| * <p>return: [mySection "mySubsection"] myKey = childValue myKey = parentValue anotherKey = | |
| * someValue | |
| * | |
| * @param projectState the project for which the plugin configuration should be returned | |
| * @param pluginName the name of the plugin for which the configuration should be returned | |
| * @return the plugin configuration from the '{@code <plugin-name>.config}' file of the specified | |
| * project with inheriting non-set parameters from the parent projects | |
| */ | |
| public Config getProjectPluginConfigWithMergedInheritance( | |
| ProjectState projectState, String pluginName) { | |
| return projectState.getConfig(pluginName + EXTENSION).getWithInheritance(/* merge= */ true); | |
| } | |
| private ProjectLevelConfig getPluginConfig(Project.NameKey projectName, String pluginName) | |
| throws NoSuchProjectException { | |
| ProjectState projectState = | |
| projectCache.get(projectName).orElseThrow(noSuchProject(projectName)); | |
| return projectState.getConfig(pluginName + EXTENSION); | |
| } | |
| @Override | |
| public synchronized void onReloadPlugin(Plugin oldPlugin, Plugin newPlugin) { | |
| pluginConfigs.remove(oldPlugin.getName()); | |
| } | |
| } |