| // 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.googlesource.gerrit.plugins.download.command.project; |
| |
| import com.google.common.collect.Maps; |
| import com.google.gerrit.extensions.annotations.PluginName; |
| import com.google.gerrit.extensions.config.DownloadCommand; |
| import com.google.gerrit.extensions.events.GitReferenceUpdatedListener; |
| import com.google.gerrit.extensions.events.LifecycleListener; |
| import com.google.gerrit.extensions.registration.DynamicMap; |
| import com.google.gerrit.extensions.registration.PrivateInternals_DynamicMapImpl; |
| import com.google.gerrit.extensions.registration.RegistrationHandle; |
| import com.google.gerrit.reviewdb.client.Project; |
| import com.google.gerrit.reviewdb.client.RefNames; |
| import com.google.gerrit.server.config.PluginConfig; |
| import com.google.gerrit.server.git.MetaDataUpdate; |
| import com.google.gerrit.server.git.ProjectConfig; |
| import com.google.gerrit.server.git.WorkQueue; |
| import com.google.gerrit.server.git.WorkQueue.Executor; |
| import com.google.gerrit.server.project.ProjectCache; |
| import com.google.gerrit.server.project.ProjectState; |
| import com.google.inject.Inject; |
| import com.google.inject.Provider; |
| import com.google.inject.Singleton; |
| |
| import org.eclipse.jgit.errors.ConfigInvalidException; |
| import org.eclipse.jgit.lib.ObjectId; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import java.io.IOException; |
| import java.util.Map; |
| |
| @Singleton |
| public class DownloadCommandUpdater implements GitReferenceUpdatedListener, |
| LifecycleListener { |
| private static final Logger log = LoggerFactory |
| .getLogger(DownloadCommandUpdater.class); |
| |
| private final String pluginName; |
| private final DynamicMap<DownloadCommand> downloadCommands; |
| private final MetaDataUpdate.Server metaDataUpdateFactory; |
| private final ProjectCache projectCache; |
| private final Map<String, ProjectDownloadCommand> projectDownloadCommands; |
| private final Map<String, RegistrationHandle> registrationHandles; |
| private final Executor executor; |
| |
| @Inject |
| DownloadCommandUpdater(@PluginName String pluginName, |
| DynamicMap<DownloadCommand> downloadCommands, |
| MetaDataUpdate.Server metaDataUpdateFactory, |
| ProjectCache projectCache, WorkQueue queue) { |
| this.pluginName = pluginName; |
| this.downloadCommands = downloadCommands; |
| this.metaDataUpdateFactory = metaDataUpdateFactory; |
| this.projectCache = projectCache; |
| this.projectDownloadCommands = Maps.newHashMap(); |
| this.registrationHandles = Maps.newHashMap(); |
| this.executor = queue.createQueue(1, "download-command-updater"); |
| } |
| |
| @Override |
| public void start() { |
| for (Project.NameKey p : projectCache.all()) { |
| ProjectState projectState = projectCache.get(p); |
| if (projectState != null) { |
| installCommandAsync(projectState); |
| } |
| } |
| } |
| |
| @Override |
| public void stop() { |
| for (RegistrationHandle rh : registrationHandles.values()) { |
| rh.remove(); |
| } |
| registrationHandles.clear(); |
| projectDownloadCommands.clear(); |
| } |
| |
| @Override |
| public void onGitReferenceUpdated(Event event) { |
| if (event.getRefName().equals(RefNames.REFS_CONFIG)) { |
| Project.NameKey p = new Project.NameKey(event.getProjectName()); |
| try { |
| ProjectConfig oldCfg = |
| ProjectConfig.read(metaDataUpdateFactory.create(p), |
| ObjectId.fromString(event.getOldObjectId())); |
| PluginConfig oldPluginCfg = oldCfg.getPluginConfig(pluginName); |
| for (String name : oldPluginCfg.getNames()) { |
| removeCommand(p, name); |
| } |
| |
| ProjectConfig newCfg = |
| ProjectConfig.read(metaDataUpdateFactory.create(p), |
| ObjectId.fromString(event.getNewObjectId())); |
| PluginConfig newPluginCfg = newCfg.getPluginConfig(pluginName); |
| for (String name : newPluginCfg.getNames()) { |
| installCommand(p, name, newPluginCfg.getString(name)); |
| } |
| } catch (IOException | ConfigInvalidException e) { |
| log.error("Failed to update download commands for project " |
| + p.get() + " on update of " + RefNames.REFS_CONFIG, e); |
| } |
| } |
| } |
| |
| private void installCommandAsync(final ProjectState p) { |
| executor.submit(new Runnable() { |
| @Override |
| public void run() { |
| PluginConfig cfg = p.getConfig().getPluginConfig(pluginName); |
| for (String name : cfg.getNames()) { |
| installCommand(p.getProject().getNameKey(), name, cfg.getString(name)); |
| } |
| } |
| }); |
| } |
| |
| private void installCommand(final Project.NameKey p, String name, |
| final String command) { |
| ProjectDownloadCommand dc = projectDownloadCommands.get(name); |
| if (dc != null) { |
| dc.add(p, command); |
| } else { |
| dc = new ProjectDownloadCommand(projectCache, p, command); |
| projectDownloadCommands.put(name, dc); |
| registrationHandles.put(name, |
| map().put(pluginName, name.replaceAll("-", " "), provider(dc))); |
| } |
| } |
| |
| private Provider<DownloadCommand> provider(final DownloadCommand dc) { |
| return new Provider<DownloadCommand>() { |
| @Override |
| public DownloadCommand get() { |
| return dc; |
| } |
| }; |
| } |
| |
| private void removeCommand(Project.NameKey p, String name) { |
| ProjectDownloadCommand dc = projectDownloadCommands.get(name); |
| dc.remove(p); |
| if (!dc.hasCommands()) { |
| registrationHandles.remove(name).remove(); |
| } |
| } |
| |
| private PrivateInternals_DynamicMapImpl<DownloadCommand> map() { |
| return (PrivateInternals_DynamicMapImpl<DownloadCommand>) downloadCommands; |
| } |
| } |