| // Copyright (C) 2012 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.pgm.init; |
| |
| import com.google.common.collect.Lists; |
| import com.google.gerrit.common.PluginData; |
| import com.google.gerrit.pgm.init.api.ConsoleUI; |
| import com.google.gerrit.pgm.init.api.InitFlags; |
| import com.google.gerrit.pgm.init.api.InitStep; |
| import com.google.gerrit.server.config.SitePaths; |
| import com.google.gerrit.server.plugins.JarPluginProvider; |
| import com.google.inject.Inject; |
| import com.google.inject.Injector; |
| import com.google.inject.Singleton; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.nio.file.Files; |
| import java.nio.file.Path; |
| import java.util.List; |
| import java.util.jar.Attributes; |
| import java.util.jar.JarFile; |
| import java.util.jar.Manifest; |
| |
| @Singleton |
| public class InitPlugins implements InitStep { |
| public static final String PLUGIN_DIR = "WEB-INF/plugins/"; |
| public static final String JAR = ".jar"; |
| |
| public static List<PluginData> listPlugins(SitePaths site, |
| PluginsDistribution pluginsDistribution) throws IOException { |
| return listPlugins(site, false, pluginsDistribution); |
| } |
| |
| public static List<PluginData> listPluginsAndRemoveTempFiles(SitePaths site, |
| PluginsDistribution pluginsDistribution) throws IOException { |
| return listPlugins(site, true, pluginsDistribution); |
| } |
| |
| private static List<PluginData> listPlugins(final SitePaths site, |
| final boolean deleteTempPluginFile, PluginsDistribution pluginsDistribution) |
| throws IOException { |
| final List<PluginData> result = Lists.newArrayList(); |
| pluginsDistribution.foreach(new PluginsDistribution.Processor() { |
| @Override |
| public void process(String pluginName, InputStream in) throws IOException { |
| Path tmpPlugin = JarPluginProvider.storeInTemp(pluginName, in, site); |
| String pluginVersion = getVersion(tmpPlugin); |
| if (deleteTempPluginFile) { |
| Files.delete(tmpPlugin); |
| } |
| result.add(new PluginData(pluginName, pluginVersion, tmpPlugin)); |
| } |
| }); |
| return result; |
| } |
| |
| private final ConsoleUI ui; |
| private final SitePaths site; |
| private final InitFlags initFlags; |
| private final InitPluginStepsLoader pluginLoader; |
| private final PluginsDistribution pluginsDistribution; |
| |
| private Injector postRunInjector; |
| |
| @Inject |
| InitPlugins(final ConsoleUI ui, final SitePaths site, |
| InitFlags initFlags, InitPluginStepsLoader pluginLoader, |
| PluginsDistribution pluginsDistribution) { |
| this.ui = ui; |
| this.site = site; |
| this.initFlags = initFlags; |
| this.pluginLoader = pluginLoader; |
| this.pluginsDistribution = pluginsDistribution; |
| } |
| |
| @Override |
| public void run() throws Exception { |
| ui.header("Plugins"); |
| |
| installPlugins(); |
| initPlugins(); |
| } |
| |
| @Override |
| public void postRun() throws Exception { |
| postInitPlugins(); |
| } |
| |
| @Inject(optional = true) |
| void setPostRunInjector(Injector injector) { |
| postRunInjector = injector; |
| } |
| |
| private void installPlugins() throws IOException { |
| List<PluginData> plugins = listPlugins(site, pluginsDistribution); |
| for (PluginData plugin : plugins) { |
| String pluginName = plugin.name; |
| try { |
| final Path tmpPlugin = plugin.pluginPath; |
| |
| if (!(initFlags.installPlugins.contains(pluginName) || ui.yesno(false, |
| "Install plugin %s version %s", pluginName, plugin.version))) { |
| Files.deleteIfExists(tmpPlugin); |
| continue; |
| } |
| |
| final Path p = site.plugins_dir.resolve(plugin.name + ".jar"); |
| if (Files.exists(p)) { |
| final String installedPluginVersion = getVersion(p); |
| if (!ui.yesno(false, |
| "version %s is already installed, overwrite it", |
| installedPluginVersion)) { |
| Files.deleteIfExists(tmpPlugin); |
| continue; |
| } |
| try { |
| Files.delete(p); |
| } catch (IOException e) { |
| throw new IOException("Failed to delete plugin " + pluginName |
| + ": " + p.toAbsolutePath(), e); |
| } |
| } |
| try { |
| Files.move(tmpPlugin, p); |
| } catch (IOException e) { |
| throw new IOException("Failed to install plugin " + pluginName |
| + ": " + tmpPlugin.toAbsolutePath() + " -> " |
| + p.toAbsolutePath(), e); |
| } |
| } finally { |
| Files.deleteIfExists(plugin.pluginPath); |
| } |
| } |
| if (plugins.isEmpty()) { |
| ui.message("No plugins found."); |
| } |
| } |
| |
| private void initPlugins() throws Exception { |
| for (InitStep initStep : pluginLoader.getInitSteps()) { |
| initStep.run(); |
| } |
| } |
| |
| private void postInitPlugins() throws Exception { |
| for (InitStep initStep : pluginLoader.getInitSteps()) { |
| postRunInjector.injectMembers(initStep); |
| initStep.postRun(); |
| } |
| } |
| |
| private static String getVersion(Path plugin) throws IOException { |
| JarFile jarFile = new JarFile(plugin.toFile()); |
| try { |
| Manifest manifest = jarFile.getManifest(); |
| Attributes main = manifest.getMainAttributes(); |
| return main.getValue(Attributes.Name.IMPLEMENTATION_VERSION); |
| } finally { |
| jarFile.close(); |
| } |
| } |
| } |