PluginLoader: Move public static methods to PluginUtil
Change-Id: Ibec943a35dc7f86c54a3315436845e0d97612857
This commit is contained in:
@@ -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();
|
||||||
|
@@ -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);
|
||||||
|
@@ -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");
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user