提交 80e78e1a 编写于 作者: K kohsuke

adding the first cut of update center capability. UI needs to follow.

git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@9691 71c3de6d-444a-0410-be80-ed276b4c234a
上级 8513ec9b
......@@ -303,6 +303,7 @@ public final class Hudson extends View implements ItemGroup<TopLevelItem>, Node,
*/
private final String secretKey;
private transient final UpdateCenter updateCenter = new UpdateCenter();
public Hudson(File root, ServletContext context) throws IOException {
this.root = root;
......@@ -394,6 +395,10 @@ public final class Hudson extends View implements ItemGroup<TopLevelItem>, Node,
return pluginManager;
}
public UpdateCenter getUpdateCenter() {
return updateCenter;
}
/**
* Returns a secret key that survives across container start/stop.
* <p>
......
package hudson.model;
import hudson.util.TextFile;
import static hudson.util.TimeUnit2.DAYS;
import net.sf.json.JSONObject;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.DataBoundConstructor;
import java.io.File;
import java.io.IOException;
import java.util.logging.Logger;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
/**
* Controls update center capability.
*
* @author Kohsuke Kawaguchi
*/
public class UpdateCenter {
private long dataTimestamp = -1;
/**
* When was the last time we asked a browser to check the data for us?
*
* <p>
* There's normally some delay between when we send HTML that includes the check code,
* until we get the data back, so this variable is used to avoid asking too many browseres
* all at once.
*/
private volatile long lastAttempt = -1;
/**
* Returns true if it's time for us to check for new version.
*/
public boolean isDue() {
long now = System.currentTimeMillis();
boolean due = now - dataTimestamp > DAY && now - lastAttempt > 15000;
if(due) lastAttempt = now;
return due;
}
/**
* This is the endpoint that receives the update center data file from the browser.
*/
public void doPostBack(StaplerRequest req) throws IOException {
dataTimestamp = System.currentTimeMillis();
String p = req.getParameter("json");
JSONObject o = JSONObject.fromObject(p);
int v = o.getInt("updateCenterVersion");
if(v !=1) {
LOGGER.warning("Unrecognized update center version: "+v);
return;
}
LOGGER.info("Obtained the latest update center data file");
getDataFile().write(p);
}
/**
* Loads the update center data, if any.
*
* @return null if no data is available.
*/
public Data getData() throws IOException {
TextFile df = getDataFile();
if(df.exists()) {
return new Data(JSONObject.fromObject(df.read()));
} else {
return null;
}
}
/**
* This is where we store the update center data.
*/
private TextFile getDataFile() {
return new TextFile(new File(Hudson.getInstance().root,"update-center.json"));
}
/**
* In-memory representation of the update center data.
*/
public static final class Data {
/**
* The latest hudson.war.
*/
public final Entry core;
/**
* Plugins in the official repository, keyed by their artifact IDs.
*/
public final Map<String,Plugin> plugins = new HashMap<String,Plugin>();
Data(JSONObject o) {
core = new Entry(o.getJSONObject("core"));
for(Map.Entry<String,JSONObject> e : (Set<Map.Entry<String,JSONObject>>)o.getJSONObject("plugins").entrySet()) {
plugins.put(e.getKey(),new Plugin(e.getValue()));
}
}
}
public static class Entry {
/**
* Artifact ID.
*/
public final String name;
/**
* The version.
*/
public final String version;
/**
* Download URL.
*/
public final String url;
public Entry(JSONObject o) {
this.name = o.getString("name");
this.version = o.getString("version");
this.url = o.getString("url");
}
}
public static final class Plugin extends Entry {
/**
* Optional URL to the Wiki page that discusses this plugin.
*/
public final String wiki;
/**
* Human readable title of the plugin, taken from Wiki page.
*/
public final String title;
@DataBoundConstructor
public Plugin(JSONObject o) {
super(o);
this.wiki = get(o,"wiki");
this.title = get(o,"title");
}
private String get(JSONObject o, String prop) {
if(o.has(prop))
return o.getString(prop);
else
return null;
}
}
private static final long DAY = DAYS.toMillis(1);
private static final Logger LOGGER = Logger.getLogger(UpdateCenter.class.getName());
}
<!--
If necessary, ask the client to fetch update-center data file for us.
This allows us to avoid proxy related configuration on the server,
and instead piggy-back on user connection.
-->
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<j:if test="${it.due}">
<script>
updateCenter.postBackURL = "${rootURL}/updateCenter/postBack";
updateCenter.version = "${h.version}";
Behaviour.addLoadEvent(updateCenter.checkUpdates);
</script>
</j:if>
</j:jelly>
\ No newline at end of file
......@@ -175,6 +175,7 @@
</a>
</td></tr>
</table>
<st:include it="${app.updateCenter}" page="main.jelly" />
</body>
</html>
</j:jelly>
\ No newline at end of file
package hudson.model;
import junit.framework.TestCase;
import net.sf.json.JSONObject;
import org.apache.commons.io.IOUtils;
import java.io.IOException;
import java.net.URL;
/**
* Quick test for {@link UpdateCenter}.
*
* @author Kohsuke Kawaguchi
*/
public class UpdateCenterTest extends TestCase {
public void testData() throws IOException {
URL url = new URL("https://hudson.dev.java.net/update-center.json?version=build");
String jsonp = IOUtils.toString(url.openStream());
String json = jsonp.substring(jsonp.indexOf('(')+1,jsonp.lastIndexOf(')'));
UpdateCenter.Data data = new UpdateCenter.Data(JSONObject.fromObject(json));
assertTrue(data.core.url.startsWith("https://hudson.dev.java.net/"));
assertTrue(data.plugins.containsKey("rake"));
System.out.println(data.core.url);
}
}
......@@ -1286,3 +1286,21 @@ var DragDrop = function(id, sGroup, config) {
}
});
})();
var updateCenter = {
postBackURL : null,
version: "?",
checkUpdates : function() {
var s = document.createElement("script");
s.setAttribute("src","https://hudson.dev.java.net/update-center.json?version="+updateCenter.version);
document.getElementsByTagName("HEAD")[0].appendChild(s);
},
post : function(data) {
new Ajax.Request(updateCenter.postBackURL, {
method:"post",
parameters:{json:Object.toJSON(data)}
});
}
};
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册