Decouple plugins from their "jar" external form

Until now all the server-side plugins have been associated
to a single jar file in the /plugin directory.

As first step to allow different forms of plugins
(e.g. script files, directories or anything else that
can provide classes and resources) we need to de-couple
the underlying Jar file from the server side plugin.

We introduce the concept of "plugin-scanner" as the interface
to scan the external form to discover:
- plugin classes
- plugin resources
- plugin meta-data (i.e. Manifest)

Change-Id: I769595a030545a5f272f453c3cf435b74719e1e7
This commit is contained in:
Luca Milanesio
2014-01-29 23:53:00 +00:00
parent 0927a52b64
commit a0c3ba5a4d
10 changed files with 320 additions and 46 deletions

View File

@@ -35,12 +35,13 @@ import com.google.inject.ProvisionException;
import org.eclipse.jgit.internal.storage.file.FileSnapshot;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
class ServerPlugin extends Plugin {
public class ServerPlugin extends Plugin {
/** Unique key that changes whenever a plugin reloads. */
public static final class CacheKey {
@@ -59,6 +60,7 @@ class ServerPlugin extends Plugin {
private final JarFile jarFile;
private final Manifest manifest;
private final PluginContentScanner scanner;
private final File dataDir;
private final String pluginCanonicalWebUrl;
private final ClassLoader classLoader;
@@ -78,28 +80,39 @@ class ServerPlugin extends Plugin {
File srcJar,
FileSnapshot snapshot,
JarFile jarFile,
Manifest manifest,
PluginContentScanner scanner,
File dataDir,
ApiType apiType,
ClassLoader classLoader,
@Nullable Class<? extends Module> sysModule,
@Nullable Class<? extends Module> sshModule,
@Nullable Class<? extends Module> httpModule) {
@Nullable Class<? extends Module> httpModule)
throws InvalidPluginException {
super(name, srcJar, pluginUser, snapshot, apiType);
this.pluginCanonicalWebUrl = pluginCanonicalWebUrl;
this.jarFile = jarFile;
this.manifest = manifest;
this.scanner = scanner;
this.dataDir = dataDir;
this.classLoader = classLoader;
this.sysModule = sysModule;
this.sshModule = sshModule;
this.httpModule = httpModule;
this.manifest = getPluginManifest(scanner);
}
File getSrcJar() {
return getSrcFile();
}
private Manifest getPluginManifest(PluginContentScanner scanner)
throws InvalidPluginException {
try {
return scanner.getManifest();
} catch (IOException e) {
throw new InvalidPluginException("Cannot get plugin manifest", e);
}
}
@Nullable
public String getVersion() {
Attributes main = manifest.getMainAttributes();
@@ -136,7 +149,7 @@ class ServerPlugin extends Plugin {
AutoRegisterModules auto = null;
if (sysModule == null && sshModule == null && httpModule == null) {
auto = new AutoRegisterModules(getName(), env, jarFile, classLoader);
auto = new AutoRegisterModules(getName(), env, scanner, classLoader);
auto.discover();
}
@@ -270,4 +283,9 @@ class ServerPlugin extends Plugin {
manager.add(handle);
}
}
@Override
public PluginContentScanner getContentScanner() {
return scanner;
}
}