PluginLoader: Move public static methods to PluginUtil

Change-Id: Ibec943a35dc7f86c54a3315436845e0d97612857
This commit is contained in:
David Pursehouse
2017-07-27 09:48:21 +01:00
parent 9d557b1316
commit eecbb4a96c
4 changed files with 112 additions and 89 deletions

View File

@@ -21,7 +21,7 @@ import com.google.gerrit.pgm.init.api.ConsoleUI;
import com.google.gerrit.pgm.init.api.InitStep; import com.google.gerrit.pgm.init.api.InitStep;
import com.google.gerrit.server.config.SitePaths; import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.plugins.JarPluginProvider; import com.google.gerrit.server.plugins.JarPluginProvider;
import com.google.gerrit.server.plugins.PluginLoader; import com.google.gerrit.server.plugins.PluginUtil;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Injector; import com.google.inject.Injector;
@@ -100,7 +100,7 @@ public class InitPluginStepsLoader {
private Injector getPluginInjector(Path jarPath) throws IOException { private Injector getPluginInjector(Path jarPath) throws IOException {
final String pluginName = final String pluginName =
MoreObjects.firstNonNull( MoreObjects.firstNonNull(
JarPluginProvider.getJarPluginName(jarPath), PluginLoader.nameOf(jarPath)); JarPluginProvider.getJarPluginName(jarPath), PluginUtil.nameOf(jarPath));
return initInjector.createChildInjector( return initInjector.createChildInjector(
new AbstractModule() { new AbstractModule() {
@Override @Override
@@ -112,7 +112,7 @@ public class InitPluginStepsLoader {
private List<Path> scanJarsInPluginsDirectory() { private List<Path> scanJarsInPluginsDirectory() {
try { try {
return PluginLoader.listPlugins(pluginsDir, ".jar"); return PluginUtil.listPlugins(pluginsDir, ".jar");
} catch (IOException e) { } catch (IOException e) {
ui.message("WARN: Cannot list %s: %s", pluginsDir.toAbsolutePath(), e.getMessage()); ui.message("WARN: Cannot list %s: %s", pluginsDir.toAbsolutePath(), e.getMessage());
return ImmutableList.of(); return ImmutableList.of();

View File

@@ -14,8 +14,6 @@
package com.google.gerrit.server.plugins; package com.google.gerrit.server.plugins;
import static com.google.gerrit.server.plugins.PluginLoader.asTemp;
import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects;
import com.google.gerrit.server.config.PluginConfig; import com.google.gerrit.server.config.PluginConfig;
import com.google.gerrit.server.config.PluginConfigFactory; import com.google.gerrit.server.config.PluginConfigFactory;
@@ -62,7 +60,7 @@ public class JarPluginProvider implements ServerPluginProvider {
@Override @Override
public String getPluginName(Path srcPath) { public String getPluginName(Path srcPath) {
try { try {
return MoreObjects.firstNonNull(getJarPluginName(srcPath), PluginLoader.nameOf(srcPath)); return MoreObjects.firstNonNull(getJarPluginName(srcPath), PluginUtil.nameOf(srcPath));
} catch (IOException e) { } catch (IOException e) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Invalid plugin file " + srcPath + ": cannot get plugin name", e); "Invalid plugin file " + srcPath + ": cannot get plugin name", e);
@@ -82,7 +80,7 @@ public class JarPluginProvider implements ServerPluginProvider {
String name = getPluginName(srcPath); String name = getPluginName(srcPath);
String extension = getExtension(srcPath); String extension = getExtension(srcPath);
try (InputStream in = Files.newInputStream(srcPath)) { try (InputStream in = Files.newInputStream(srcPath)) {
Path tmp = asTemp(in, tempNameFor(name), extension, tmpDir); Path tmp = PluginUtil.asTemp(in, tempNameFor(name), extension, tmpDir);
return loadJarPlugin(name, srcPath, snapshot, tmp, description); return loadJarPlugin(name, srcPath, snapshot, tmp, description);
} }
} catch (IOException e) { } catch (IOException e) {
@@ -114,7 +112,7 @@ public class JarPluginProvider implements ServerPluginProvider {
if (!Files.exists(sitePaths.tmp_dir)) { if (!Files.exists(sitePaths.tmp_dir)) {
Files.createDirectories(sitePaths.tmp_dir); Files.createDirectories(sitePaths.tmp_dir);
} }
return asTemp(in, tempNameFor(pluginName), ".jar", sitePaths.tmp_dir); return PluginUtil.asTemp(in, tempNameFor(pluginName), ".jar", sitePaths.tmp_dir);
} }
private ServerPlugin loadJarPlugin( private ServerPlugin loadJarPlugin(
@@ -138,7 +136,7 @@ public class JarPluginProvider implements ServerPluginProvider {
urls.add(tmp.toUri().toURL()); urls.add(tmp.toUri().toURL());
ClassLoader pluginLoader = ClassLoader pluginLoader =
new URLClassLoader(urls.toArray(new URL[urls.size()]), PluginLoader.parentFor(type)); new URLClassLoader(urls.toArray(new URL[urls.size()]), PluginUtil.parentFor(type));
JarScanner jarScanner = createJarScanner(tmp); JarScanner jarScanner = createJarScanner(tmp);
PluginConfig pluginConfig = configFactory.getFromGerritConfig(name); PluginConfig pluginConfig = configFactory.getFromGerritConfig(name);

View File

@@ -17,21 +17,16 @@ package com.google.gerrit.server.plugins;
import com.google.common.base.CharMatcher; import com.google.common.base.CharMatcher;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects;
import com.google.common.base.Strings;
import com.google.common.collect.ComparisonChain; import com.google.common.collect.ComparisonChain;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Ordering;
import com.google.common.collect.SetMultimap; import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.google.common.io.ByteStreams;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.events.LifecycleListener; import com.google.gerrit.extensions.events.LifecycleListener;
import com.google.gerrit.extensions.systemstatus.ServerInformation; import com.google.gerrit.extensions.systemstatus.ServerInformation;
import com.google.gerrit.extensions.webui.JavaScriptPlugin;
import com.google.gerrit.server.PluginUser; import com.google.gerrit.server.PluginUser;
import com.google.gerrit.server.cache.PersistentCacheFactory; import com.google.gerrit.server.cache.PersistentCacheFactory;
import com.google.gerrit.server.config.CanonicalWebUrl; import com.google.gerrit.server.config.CanonicalWebUrl;
@@ -44,7 +39,6 @@ import com.google.inject.Provider;
import com.google.inject.Singleton; import com.google.inject.Singleton;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.DirectoryStream; import java.nio.file.DirectoryStream;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
@@ -74,7 +68,7 @@ public class PluginLoader implements LifecycleListener {
private static final Logger log = LoggerFactory.getLogger(PluginLoader.class); private static final Logger log = LoggerFactory.getLogger(PluginLoader.class);
public String getPluginName(Path srcPath) { public String getPluginName(Path srcPath) {
return MoreObjects.firstNonNull(getGerritPluginName(srcPath), nameOf(srcPath)); return MoreObjects.firstNonNull(getGerritPluginName(srcPath), PluginUtil.nameOf(srcPath));
} }
private final Path pluginsDir; private final Path pluginsDir;
@@ -139,32 +133,6 @@ public class PluginLoader implements LifecycleListener {
} }
} }
public static List<Path> listPlugins(Path pluginsDir, String suffix) throws IOException {
if (pluginsDir == null || !Files.exists(pluginsDir)) {
return ImmutableList.of();
}
DirectoryStream.Filter<Path> filter =
new DirectoryStream.Filter<Path>() {
@Override
public boolean accept(Path entry) throws IOException {
String n = entry.getFileName().toString();
boolean accept =
!n.startsWith(".last_") && !n.startsWith(".next_") && Files.isRegularFile(entry);
if (!Strings.isNullOrEmpty(suffix)) {
accept &= n.endsWith(suffix);
}
return accept;
}
};
try (DirectoryStream<Path> files = Files.newDirectoryStream(pluginsDir, filter)) {
return Ordering.natural().sortedCopy(files);
}
}
public static List<Path> listPlugins(Path pluginsDir) throws IOException {
return listPlugins(pluginsDir, null);
}
public boolean isRemoteAdminEnabled() { public boolean isRemoteAdminEnabled() {
return remoteAdmin; return remoteAdmin;
} }
@@ -191,8 +159,8 @@ public class PluginLoader implements LifecycleListener {
checkRemoteInstall(); checkRemoteInstall();
String fileName = originalName; String fileName = originalName;
Path tmp = asTemp(in, ".next_" + fileName + "_", ".tmp", pluginsDir); Path tmp = PluginUtil.asTemp(in, ".next_" + fileName + "_", ".tmp", pluginsDir);
String name = MoreObjects.firstNonNull(getGerritPluginName(tmp), nameOf(fileName)); String name = MoreObjects.firstNonNull(getGerritPluginName(tmp), PluginUtil.nameOf(fileName));
if (!originalName.equals(name)) { if (!originalName.equals(name)) {
log.warn( log.warn(
String.format( String.format(
@@ -230,20 +198,6 @@ public class PluginLoader implements LifecycleListener {
return name; return name;
} }
static Path asTemp(InputStream in, String prefix, String suffix, Path dir) throws IOException {
Path tmp = Files.createTempFile(dir, prefix, suffix);
boolean keep = false;
try (OutputStream out = Files.newOutputStream(tmp)) {
ByteStreams.copy(in, out);
keep = true;
return tmp;
} finally {
if (!keep) {
Files.delete(tmp);
}
}
}
private synchronized void unloadPlugin(Plugin plugin) { private synchronized void unloadPlugin(Plugin plugin) {
persistentCacheFactory.onStop(plugin); persistentCacheFactory.onStop(plugin);
String name = plugin.getName(); String name = plugin.getName();
@@ -594,19 +548,7 @@ public class PluginLoader implements LifecycleListener {
} }
} }
public static String nameOf(Path plugin) { private String getExtension(String name) {
return nameOf(plugin.getFileName().toString());
}
private static String nameOf(String name) {
if (name.endsWith(".disabled")) {
name = name.substring(0, name.lastIndexOf('.'));
}
int ext = name.lastIndexOf('.');
return 0 < ext ? name.substring(0, ext) : name;
}
private static String getExtension(String name) {
int ext = name.lastIndexOf('.'); int ext = name.lastIndexOf('.');
return 0 < ext ? name.substring(ext) : ""; return 0 < ext ? name.substring(ext) : "";
} }
@@ -651,22 +593,9 @@ public class PluginLoader implements LifecycleListener {
getPluginDataDir(name))); getPluginDataDir(name)));
} }
static ClassLoader parentFor(Plugin.ApiType type) throws InvalidPluginException {
switch (type) {
case EXTENSION:
return PluginName.class.getClassLoader();
case PLUGIN:
return PluginLoader.class.getClassLoader();
case JS:
return JavaScriptPlugin.class.getClassLoader();
default:
throw new InvalidPluginException("Unsupported ApiType " + type);
}
}
// Only one active plugin per plugin name can exist for each plugin name. // Only one active plugin per plugin name can exist for each plugin name.
// Filter out disabled plugins and transform the multimap to a map // Filter out disabled plugins and transform the multimap to a map
private static Map<String, Path> filterDisabled(SetMultimap<String, Path> pluginPaths) { private Map<String, Path> filterDisabled(SetMultimap<String, Path> pluginPaths) {
Map<String, Path> activePlugins = Maps.newHashMapWithExpectedSize(pluginPaths.keys().size()); Map<String, Path> activePlugins = Maps.newHashMapWithExpectedSize(pluginPaths.keys().size());
for (String name : pluginPaths.keys()) { for (String name : pluginPaths.keys()) {
for (Path pluginPath : pluginPaths.asMap().get(name)) { for (Path pluginPath : pluginPaths.asMap().get(name)) {
@@ -733,14 +662,14 @@ public class PluginLoader implements LifecycleListener {
private List<Path> scanPathsInPluginsDirectory(Path pluginsDir) { private List<Path> scanPathsInPluginsDirectory(Path pluginsDir) {
try { try {
return listPlugins(pluginsDir); return PluginUtil.listPlugins(pluginsDir);
} catch (IOException e) { } catch (IOException e) {
log.error("Cannot list " + pluginsDir.toAbsolutePath(), e); log.error("Cannot list " + pluginsDir.toAbsolutePath(), e);
return ImmutableList.of(); return ImmutableList.of();
} }
} }
private static Iterable<Path> filterDisabledPlugins(Collection<Path> paths) { private Iterable<Path> filterDisabledPlugins(Collection<Path> paths) {
return Iterables.filter(paths, p -> !p.getFileName().toString().endsWith(".disabled")); return Iterables.filter(paths, p -> !p.getFileName().toString().endsWith(".disabled"));
} }
@@ -763,11 +692,11 @@ public class PluginLoader implements LifecycleListener {
return map; return map;
} }
private static boolean isUiPlugin(String name) { private boolean isUiPlugin(String name) {
return isPlugin(name, "js") || isPlugin(name, "html"); return isPlugin(name, "js") || isPlugin(name, "html");
} }
private static boolean isPlugin(String fileName, String ext) { private boolean isPlugin(String fileName, String ext) {
String fullExt = "." + ext; String fullExt = "." + ext;
return fileName.endsWith(fullExt) || fileName.endsWith(fullExt + ".disabled"); return fileName.endsWith(fullExt) || fileName.endsWith(fullExt + ".disabled");
} }

View File

@@ -0,0 +1,96 @@
// Copyright (C) 2017 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.plugins;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Ordering;
import com.google.common.io.ByteStreams;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.webui.JavaScriptPlugin;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
public class PluginUtil {
public static List<Path> listPlugins(Path pluginsDir, String suffix) throws IOException {
if (pluginsDir == null || !Files.exists(pluginsDir)) {
return ImmutableList.of();
}
DirectoryStream.Filter<Path> filter =
new DirectoryStream.Filter<Path>() {
@Override
public boolean accept(Path entry) throws IOException {
String n = entry.getFileName().toString();
boolean accept =
!n.startsWith(".last_") && !n.startsWith(".next_") && Files.isRegularFile(entry);
if (!Strings.isNullOrEmpty(suffix)) {
accept &= n.endsWith(suffix);
}
return accept;
}
};
try (DirectoryStream<Path> files = Files.newDirectoryStream(pluginsDir, filter)) {
return Ordering.natural().sortedCopy(files);
}
}
static List<Path> listPlugins(Path pluginsDir) throws IOException {
return listPlugins(pluginsDir, null);
}
static Path asTemp(InputStream in, String prefix, String suffix, Path dir) throws IOException {
Path tmp = Files.createTempFile(dir, prefix, suffix);
boolean keep = false;
try (OutputStream out = Files.newOutputStream(tmp)) {
ByteStreams.copy(in, out);
keep = true;
return tmp;
} finally {
if (!keep) {
Files.delete(tmp);
}
}
}
public static String nameOf(Path plugin) {
return nameOf(plugin.getFileName().toString());
}
static String nameOf(String name) {
if (name.endsWith(".disabled")) {
name = name.substring(0, name.lastIndexOf('.'));
}
int ext = name.lastIndexOf('.');
return 0 < ext ? name.substring(0, ext) : name;
}
static ClassLoader parentFor(Plugin.ApiType type) throws InvalidPluginException {
switch (type) {
case EXTENSION:
return PluginName.class.getClassLoader();
case PLUGIN:
return PluginLoader.class.getClassLoader();
case JS:
return JavaScriptPlugin.class.getClassLoader();
default:
throw new InvalidPluginException("Unsupported ApiType " + type);
}
}
}