Author: bombe
Date: 2007-11-10 13:40:29 +0000 (Sat, 10 Nov 2007)
New Revision: 15739
Modified:
trunk/freenet/src/freenet/clients/http/PproxyToadlet.java
trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties
trunk/freenet/src/freenet/pluginmanager/PluginHandler.java
trunk/freenet/src/freenet/pluginmanager/PluginInfoWrapper.java
trunk/freenet/src/freenet/pluginmanager/PluginManager.java
Log:
remove "refresh-on-startup" option totally
add "purge from cache" option to plugin unloading and reloading
add method to remove plugin from local cache to plugin manager
Modified: trunk/freenet/src/freenet/clients/http/PproxyToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/PproxyToadlet.java 2007-11-10
12:18:22 UTC (rev 15738)
+++ trunk/freenet/src/freenet/clients/http/PproxyToadlet.java 2007-11-10
13:40:29 UTC (rev 15739)
@@ -119,16 +119,16 @@
{
final boolean logMINOR = Logger.shouldLog(Logger.MINOR,
this);
final boolean logNORMAL =
Logger.shouldLog(Logger.NORMAL, this);
+ PageMaker pageMaker = ctx.getPageMaker();
if (request.isPartSet("submit-official") ||
request.isPartSet("submit-other")) {
String pluginName = null;
- boolean refresh =
request.isPartSet("refresh-on-startup");
if (request.isPartSet("submit-official")) {
pluginName =
request.getPartAsString("plugin-name", 40);
} else {
pluginName =
request.getPartAsString("plugin-url", 200);
}
- pm.startPlugin(pluginName, refresh, true);
+ pm.startPlugin(pluginName, true);
headers.put("Location", ".");
ctx.sendReplyHeaders(302, "Found", headers,
null, 0);
return;
@@ -140,71 +140,80 @@
ctx.sendReplyHeaders(302, "Found", headers,
null, 0);
return;
}
- if (request.isPartSet("change-reload-submit")) {
- int pluginInfoWrapperHashCode =
request.getIntPart("plugin-id", -1);
- boolean newReload =
request.isPartSet("reload-on-startup");
- Iterator/*<PluginInfoWrapper>*/ pluginIterator
= pm.getPlugins().iterator();
- while (pluginIterator.hasNext()) {
- PluginInfoWrapper pluginInfoWrapper =
(PluginInfoWrapper) pluginIterator.next();
- if (pluginInfoWrapper.hashCode() ==
pluginInfoWrapperHashCode) {
-
pluginInfoWrapper.setAutoRefresh(newReload);
- break;
- }
- }
- headers.put("Location", ".");
- ctx.sendReplyHeaders(302, "Found", headers,
null, 0);
- return;
- }
if (request.isPartSet("cancel")){
headers.put("Location", "/plugins/");
ctx.sendReplyHeaders(302, "Found", headers,
null, 0);
return;
}
if (request.getPartAsString("unloadconfirm",
MAX_PLUGIN_NAME_LENGTH).length() > 0) {
-
pm.killPlugin(request.getPartAsString("unloadconfirm", MAX_PLUGIN_NAME_LENGTH),
MAX_THREADED_UNLOAD_WAIT_TIME);
- HTMLNode pageNode =
ctx.getPageMaker().getPageNode(l10n("plugins"), ctx);
- HTMLNode contentNode =
ctx.getPageMaker().getContentNode(pageNode);
+ String pluginThreadName =
request.getPartAsString("unloadconfirm", MAX_PLUGIN_NAME_LENGTH);
+ String pluginSpecification =
getPluginSpecification(pm, pluginThreadName);
+ pm.killPlugin(pluginThreadName,
MAX_THREADED_UNLOAD_WAIT_TIME);
+ if (request.isPartSet("purge")) {
+
pm.removeCachedCopy(pluginSpecification);
+ }
+ HTMLNode pageNode =
pageMaker.getPageNode(l10n("plugins"), ctx);
+ HTMLNode contentNode =
pageMaker.getContentNode(pageNode);
HTMLNode infobox = contentNode.addChild("div",
"class", "infobox infobox-success");
infobox.addChild("div", "class",
"infobox-header", l10n("pluginUnloaded"));
HTMLNode infoboxContent =
infobox.addChild("div", "class", "infobox-content");
- infoboxContent.addChild("#",
l10n("pluginUnloadedWithName", "name", request.getPartAsString("remove",
MAX_PLUGIN_NAME_LENGTH)));
+ infoboxContent.addChild("#",
l10n("pluginUnloadedWithName", "name", pluginThreadName));
infoboxContent.addChild("br");
infoboxContent.addChild("a", "href",
"/plugins/", l10n("returnToPluginPage"));
writeHTMLReply(ctx, 200, "OK",
pageNode.generate());
return;
}if (request.getPartAsString("unload",
MAX_PLUGIN_NAME_LENGTH).length() > 0) {
- HTMLNode pageNode =
ctx.getPageMaker().getPageNode(l10n("plugins"), ctx);
- HTMLNode contentNode =
ctx.getPageMaker().getContentNode(pageNode);
+ HTMLNode pageNode =
pageMaker.getPageNode(l10n("plugins"), ctx);
+ HTMLNode contentNode =
pageMaker.getContentNode(pageNode);
HTMLNode infobox = contentNode.addChild("div",
"class", "infobox infobox-query");
infobox.addChild("div", "class",
"infobox-header", l10n("unloadPluginTitle"));
HTMLNode infoboxContent =
infobox.addChild("div", "class", "infobox-content");
infoboxContent.addChild("#",
l10n("unloadPluginWithName", "name", request.getPartAsString("unload",
MAX_PLUGIN_NAME_LENGTH)));
HTMLNode unloadForm =
ctx.addFormChild(infoboxContent,
"/plugins/", "unloadPluginConfirmForm");
- unloadForm.addChild("input", new String[] {
"type", "name", "value" }, new String[] { "submit", "cancel",
L10n.getString("Toadlet.cancel") });
unloadForm.addChild("input", new String[] {
"type", "name", "value" }, new String[] { "hidden", "unloadconfirm",
request.getPartAsString("unload", MAX_PLUGIN_NAME_LENGTH) });
- unloadForm.addChild("input", new String[] {
"type", "name", "value" }, new String[] { "submit", "confirm", l10n("unload")
});
+ HTMLNode tempNode = unloadForm.addChild("p");
+ tempNode.addChild("input", new String[] {
"type", "name" }, new String[] { "checkbox", "purge" });
+ tempNode.addChild("#", l10n("unloadPurge"));
+ tempNode = unloadForm.addChild("p");
+ tempNode.addChild("input", new String[] {
"type", "name", "value" }, new String[] { "submit", "confirm", l10n("unload")
});
+ tempNode.addChild("#", " ");
+ tempNode.addChild("input", new String[] {
"type", "name", "value" }, new String[] { "submit", "cancel",
L10n.getString("Toadlet.cancel") });
writeHTMLReply(ctx, 200, "OK",
pageNode.generate());
return;
- }else if (request.getPartAsString("reload",
MAX_PLUGIN_NAME_LENGTH).length() > 0) {
- String fn = null;
- boolean refresh = false;
- Iterator it = pm.getPlugins().iterator();
- while (it.hasNext()) {
- PluginInfoWrapper pi =
(PluginInfoWrapper) it.next();
- if
(pi.getThreadName().equals(request.getPartAsString("reload",
MAX_PLUGIN_NAME_LENGTH))) {
- fn = pi.getFilename();
- refresh = pi.isAutoRefresh();
- break;
- }
- }
+ } else if (request.getPartAsString("reload",
MAX_PLUGIN_NAME_LENGTH).length() > 0) {
+ HTMLNode pageNode =
pageMaker.getPageNode(l10n("plugins"), ctx);
+ HTMLNode contentNode =
pageMaker.getContentNode(pageNode);
+ HTMLNode reloadBox =
contentNode.addChild(pageMaker.getInfobox("infobox infobox-query",
l10n("reloadPluginTitle")));
+ HTMLNode reloadContent =
pageMaker.getContentNode(reloadBox);
+ reloadContent.addChild("p",
l10n("reloadExplanation"));
+ reloadContent.addChild("p",
l10n("reloadWarning"));
+ HTMLNode reloadForm =
ctx.addFormChild(reloadContent, "/plugins/", "reloadPluginConfirmForm");
+ reloadForm.addChild("input", new String[] {
"type", "name", "value" }, new String[] { "hidden", "reloadconfirm",
request.getPartAsString("reload", MAX_PLUGIN_NAME_LENGTH) });
+ HTMLNode tempNode = reloadForm.addChild("p");
+ tempNode.addChild("input", new String[] {
"type", "name" }, new String[] { "checkbox", "purge" });
+ tempNode.addChild("#",
l10n("reloadPurgeWarning"));
+ tempNode = reloadForm.addChild("p");
+ tempNode.addChild("input", new String[] {
"type", "name", "value" }, new String[] { "submit", "confirm", l10n("reload")
});
+ tempNode.addChild("#", " ");
+ tempNode.addChild("input", new String[] {
"type", "name", "value" }, new String[] { "submit", "cancel",
L10n.getString("Toadlet.cancel") });
+
+ writeHTMLReply(ctx, 200, "OK",
pageNode.generate());
+ return;
+ }else if (request.getPartAsString("reloadconfirm",
MAX_PLUGIN_NAME_LENGTH).length() > 0) {
+ boolean purge = request.isPartSet("purge");
+ String pluginThreadName =
request.getPartAsString("reloadconfirm", MAX_PLUGIN_NAME_LENGTH);
+ String fn = getPluginSpecification(pm,
pluginThreadName);
if (fn == null) {
sendErrorPage(ctx, 404,
l10n("pluginNotFoundReloadTitle"),
L10n.getString("PluginToadlet.pluginNotFoundReload"));
} else {
-
pm.killPlugin(request.getPartAsString("reload", MAX_PLUGIN_NAME_LENGTH),
MAX_THREADED_UNLOAD_WAIT_TIME);
- pm.startPlugin(fn, refresh, true);
+ pm.killPlugin(pluginThreadName,
MAX_THREADED_UNLOAD_WAIT_TIME);
+ if (purge) {
+ pm.removeCachedCopy(fn);
+ }
+ pm.startPlugin(fn, true);
headers.put("Location", ".");
ctx.sendReplyHeaders(302, "Found",
headers, null, 0);
@@ -220,6 +229,28 @@
}
+ /**
+ * Searches all plugins for the plugin with the given thread name and
+ * returns the plugin specification used to load the plugin.
+ *
+ * @param pluginManager
+ * The plugin manager
+ * @param pluginThreadName
+ * The thread name of the plugin
+ * @return The plugin specification of the plugin, or <code>null</code>
if
+ * no plugin was found
+ */
+ private String getPluginSpecification(PluginManager pluginManager,
String pluginThreadName) {
+ Iterator it = pluginManager.getPlugins().iterator();
+ while (it.hasNext()) {
+ PluginInfoWrapper pi = (PluginInfoWrapper) it.next();
+ if (pi.getThreadName().equals(pluginThreadName)) {
+ return pi.getFilename();
+ }
+ }
+ return null;
+ }
+
private String l10n(String key, String pattern, String value) {
return L10n.getString("PproxyToadlet."+key, new String[] {
pattern }, new String[] { value });
}
@@ -393,7 +424,6 @@
headerRow.addChild("th", l10n("classNameTitle"));
headerRow.addChild("th", l10n("internalIDTitle"));
headerRow.addChild("th", l10n("startedAtTitle"));
- headerRow.addChild("th", l10n("reloadOnStartupShort"));
headerRow.addChild("th");
headerRow.addChild("th");
headerRow.addChild("th");
@@ -404,14 +434,6 @@
pluginRow.addChild("td",
pi.getPluginClassName());
pluginRow.addChild("td", pi.getThreadName());
pluginRow.addChild("td", new
Date(pi.getStarted()).toString());
- HTMLNode autoReloadChangeForm =
ctx.addFormChild(pluginRow.addChild("td", "align", "center"), ".",
"changeAutoReloadForm");
- if (pi.isAutoRefresh()) {
- autoReloadChangeForm.addChild("input",
new String[] { "name", "type", "checked" }, new String[] { "reload-on-startup",
"checkbox", "checked" });
- } else {
- autoReloadChangeForm.addChild("input",
new String[] { "name", "type" }, new String[] { "reload-on-startup", "checkbox"
});
- }
- autoReloadChangeForm.addChild("input", new
String[] { "name", "type", "value" }, new String[] { "plugin-id", "hidden",
String.valueOf(pi.hashCode()) });
- autoReloadChangeForm.addChild("input", new
String[] { "name", "type", "value" }, new String[] { "change-reload-submit",
"submit", l10n("changeReloadOnStartup") });
if (pi.isStopping()) {
pluginRow.addChild("td",
l10n("pluginStopping"));
/* add two empty cells. */
@@ -448,8 +470,7 @@
String pluginName = (String)
availablePluginIterator.next();
selectNode.addChild("option", "value", pluginName,
pluginName);
}
- addOfficialForm.addChild("input", new String[] { "type",
"name", "value" }, new String[] { "checkbox", "refresh-on-startup", "true" });
- addOfficialForm.addChild("#", l10n("refreshOnStartup"));
+ addOfficialForm.addChild("#", " ");
addOfficialForm.addChild("input", new String[] { "type",
"name", "value" }, new String[] { "submit", "submit-official", l10n("Load") });
}
@@ -462,8 +483,7 @@
addOtherForm.addChild("div", l10n("loadOtherPluginText"));
addOtherForm.addChild("#", (l10n("loadOtherURLLabel") + ": "));
addOtherForm.addChild("input", new String[] { "type", "name",
"size" }, new String[] { "text", "plugin-url", "80" });
- addOtherForm.addChild("input", new String[] { "type", "name",
"value" }, new String[] { "checkbox", "refresh-on-startup", "true" });
- addOtherForm.addChild("#", l10n("refreshOnStartup"));
+ addOtherForm.addChild("#", " ");
addOtherForm.addChild("input", new String[] { "type", "name",
"value" }, new String[] { "submit", "submit-other", l10n("Load") });
}
Modified: trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties
===================================================================
--- trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties 2007-11-10
12:18:22 UTC (rev 15738)
+++ trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties 2007-11-10
13:40:29 UTC (rev 15739)
@@ -725,6 +725,10 @@
PproxyToadlet.pluginsWithNodeName=Plugins of ${name}
PproxyToadlet.reloadOnStartupShort=Reload on Startup
PproxyToadlet.reload=Reload
+PproxyToadlet.reloadPluginTitle=Reload Plugin
+PproxyToadlet.reloadExplanation=Reloading a plugin is the same as unloading it
and then loading it again.
+PproxyToadlet.reloadWarning=Be warned that some plugins do not handle a reload
gracefully!
+PproxyToadlet.reloadPurgeWarning=Remove the plugin from the cache before
reloading. If the plugin was loaded from the internet it will be downloaded
again!
PproxyToadlet.refreshOnStartup=Reload from server on startup
PproxyToadlet.returnToPluginPage=Return to plugin page
PproxyToadlet.startedAtTitle=Started at
@@ -742,6 +746,7 @@
PproxyToadlet.unload=Unload
PproxyToadlet.unloadPluginTitle=Unload plugin?
PproxyToadlet.unloadPluginWithName=Are you sure you wish to unload ${name}?
+PproxyToadlet.unloadPurge=Remove plugin from cache
QueueToadlet.DUinProgress=Directory uploads in progress
QueueToadlet.DinProgress=Downloads in progress
QueueToadlet.UinProgress=Uploads in progress
Modified: trunk/freenet/src/freenet/pluginmanager/PluginHandler.java
===================================================================
--- trunk/freenet/src/freenet/pluginmanager/PluginHandler.java 2007-11-10
12:18:22 UTC (rev 15738)
+++ trunk/freenet/src/freenet/pluginmanager/PluginHandler.java 2007-11-10
13:40:29 UTC (rev 15739)
@@ -19,8 +19,8 @@
*
* @param plug
*/
- public static PluginInfoWrapper startPlugin(PluginManager pm, String
filename, FredPlugin plug, PluginRespirator pr, boolean refresh) {
- final PluginInfoWrapper pi = new PluginInfoWrapper(plug,
filename, refresh);
+ public static PluginInfoWrapper startPlugin(PluginManager pm, String
filename, FredPlugin plug, PluginRespirator pr) {
+ final PluginInfoWrapper pi = new PluginInfoWrapper(plug,
filename);
final PluginStarter ps = new PluginStarter(pr, pi);
ps.setPlugin(pm, plug);
// We must start the plugin *after startup has finished*
Modified: trunk/freenet/src/freenet/pluginmanager/PluginInfoWrapper.java
===================================================================
--- trunk/freenet/src/freenet/pluginmanager/PluginInfoWrapper.java
2007-11-10 12:18:22 UTC (rev 15738)
+++ trunk/freenet/src/freenet/pluginmanager/PluginInfoWrapper.java
2007-11-10 13:40:29 UTC (rev 15739)
@@ -20,14 +20,13 @@
private boolean isIPDetectorPlugin;
private boolean isPortForwardPlugin;
private boolean isMultiplePlugin;
- private boolean autoRefresh;
private String filename;
private HashSet toadletLinks=new HashSet();
private boolean stopping = false;
private boolean unregistered = false;
//public String
- public PluginInfoWrapper(FredPlugin plug, String filename, boolean
autoRefresh) {
+ public PluginInfoWrapper(FredPlugin plug, String filename) {
this.plug = plug;
if (fedPluginThread) return;
className = plug.getClass().toString();
@@ -40,31 +39,8 @@
isIPDetectorPlugin = (plug instanceof FredPluginIPDetector);
isPortForwardPlugin = (plug instanceof FredPluginPortForward);
isMultiplePlugin = (plug instanceof FredPluginMultiple);
- this.autoRefresh = autoRefresh;
}
- /**
- * Returns whether this plugin should be refreshed from the server on
- * startup.
- *
- * @return <code>true</code> if the plugin should be refresh on startup,
- * <code>false</code> otherwise
- */
- public boolean isAutoRefresh() {
- return autoRefresh;
- }
-
- /**
- * Sets the new value for the refresh-on-startup feature.
- *
- * @param autoRefresh
- * <code>true</code> if the plugin should be reloaded on
- * startup, <code>false</code> otherwise
- */
- public void setAutoRefresh(boolean autoRefresh) {
- this.autoRefresh = autoRefresh;
- }
-
void setThread(Thread ps) {
if(thread != null)
throw new IllegalStateException("Already set a thread");
Modified: trunk/freenet/src/freenet/pluginmanager/PluginManager.java
===================================================================
--- trunk/freenet/src/freenet/pluginmanager/PluginManager.java 2007-11-10
12:18:22 UTC (rev 15738)
+++ trunk/freenet/src/freenet/pluginmanager/PluginManager.java 2007-11-10
13:40:29 UTC (rev 15739)
@@ -85,11 +85,13 @@
if (fns != null) {
for (int i = 0; i < fns.length; i++) {
String name = fns[i];
+ /* FIXME - compatibility code, remove somewhen
*/
boolean refresh = name.endsWith("*");
if (refresh) {
name = name.substring(0, name.length()
- 1);
}
- startPlugin(name, refresh, false);
+ /* FIXME - end of compatibility code */
+ startPlugin(name, false);
}
}
@@ -111,7 +113,7 @@
while (it.hasNext()) {
PluginInfoWrapper pluginInfoWrapper =
(PluginInfoWrapper) it.next();
- v.add(pluginInfoWrapper.getFilename() +
(pluginInfoWrapper.isAutoRefresh() ? "*" : ""));
+ v.add(pluginInfoWrapper.getFilename());
}
return (String[]) v.toArray(new String[v.size()]);
@@ -132,7 +134,7 @@
}
}
- public void startPlugin(final String filename, final boolean refresh,
final boolean store) {
+ public void startPlugin(final String filename, final boolean store) {
if (filename.trim().length() == 0)
return;
final PluginProgress pluginProgress = new
PluginProgress(filename);
@@ -145,9 +147,9 @@
Logger.normal(this, "Loading plugin: " +
filename);
FredPlugin plug;
try {
- plug = loadPlugin(filename, refresh);
+ plug = loadPlugin(filename);
pluginProgress.setProgress(PluginProgress.STARTING);
- PluginInfoWrapper pi =
PluginHandler.startPlugin(PluginManager.this, filename, plug, new
PluginRespirator(node, PluginManager.this), refresh);
+ PluginInfoWrapper pi =
PluginHandler.startPlugin(PluginManager.this, filename, plug, new
PluginRespirator(node, PluginManager.this));
synchronized (pluginWrappers) {
pluginWrappers.add(pi);
}
@@ -244,6 +246,30 @@
core.storeConfig();
}
+ /**
+ * Removes the cached copy of the given plugin from the plugins/
directory.
+ *
+ * @param pluginSpecification
+ * The plugin specification
+ */
+ public void removeCachedCopy(String pluginSpecification) {
+ int lastSlash = pluginSpecification.lastIndexOf('/');
+ File pluginFile;
+ if (lastSlash == -1) {
+ /* Windows, maybe? */
+ lastSlash = pluginSpecification.lastIndexOf('\\');
+ }
+ if (lastSlash == -1) {
+ /* it's an official plugin! */
+ pluginFile = new File("plugins", pluginSpecification +
".jar.url");
+ } else {
+ pluginFile = new File("plugins",
pluginSpecification.substring(lastSlash + 1));
+ }
+ if (pluginFile.exists()) {
+ pluginFile.delete();
+ }
+ }
+
public void unregisterPluginToadlet(PluginInfoWrapper pi) {
synchronized (toadletList) {
try {
@@ -383,22 +409,19 @@
/**
* Tries to load a plugin from the given name. If the name only
contains the
- * name of a plugin and the plugin should not be refreshed on startup
it is
- * loaded from the plugin directory, if found, otherwise it's refresh
from
- * the project server. If the name contains a complete url and the short
- * file already exists in the plugin directory and the plugin should
not be
- * refreshed, it's loaded from the plugin directory, otherwise it's
- * retrieved from the remote server.
+ * name of a plugin it is loaded from the plugin directory, if found,
+ * otherwise it's loaded from the project server. If the name contains a
+ * complete url and the short file already exists in the plugin
directory
+ * it's loaded from the plugin directory, otherwise it's retrieved from
the
+ * remote server.
*
* @param name
* The specification of the plugin
- * @param refresh
- * Whether the file should be refreshed on startup
* @return An instanciated object of the plugin
* @throws PluginNotFoundException
* If anything goes wrong.
*/
- private FredPlugin loadPlugin(String name, boolean refresh) throws
PluginNotFoundException {
+ private FredPlugin loadPlugin(String name) throws
PluginNotFoundException {
URL pluginUrl = null;
/* check if name is a local file. */
File pluginFile = new File(name);
@@ -440,7 +463,7 @@
if (logMINOR) {
Logger.minor(this, "plugin file " +
pluginFile.getAbsolutePath() + " exists: " + pluginFile.exists());
}
- if (refresh || !pluginFile.exists()) {
+ if (!pluginFile.exists()) {
File tempPluginFile = null;
OutputStream pluginOutputStream = null;
URLConnection urlConnection = null;