提交 76832379 编写于 作者: K Kohsuke Kawaguchi

exposed data about installed plugins, installable plugins, update center jobs,...

exposed data about installed plugins, installable plugins, update center jobs, etc., to the REST API
上级 5dd51297
......@@ -55,7 +55,8 @@ Upcoming changes</a>
<!-- Record your changes in the trunk here. -->
<div id="trunk" style="display:none"><!--=TRUNK-BEGIN=-->
<ul class=image>
<li class=>
<li class=rfe>
Exposed plugin manager and update center to the REST API
</ul>
</div><!--=TRUNK-END=-->
......
......@@ -29,6 +29,7 @@ import hudson.init.InitStrategy;
import hudson.init.InitializerFinder;
import hudson.model.AbstractModelObject;
import hudson.model.AdministrativeMonitor;
import hudson.model.Api;
import hudson.model.Descriptor;
import hudson.model.Failure;
import hudson.model.UpdateCenter;
......@@ -60,6 +61,8 @@ import org.kohsuke.stapler.HttpResponses;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.export.Exported;
import org.kohsuke.stapler.export.ExportedBean;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
......@@ -93,6 +96,7 @@ import static hudson.init.InitMilestone.*;
*
* @author Kohsuke Kawaguchi
*/
@ExportedBean
public abstract class PluginManager extends AbstractModelObject {
/**
* All discovered plugins.
......@@ -157,6 +161,10 @@ public abstract class PluginManager extends AbstractModelObject {
strategy = createPluginStrategy();
}
public Api getApi() {
return new Api(this);
}
/**
* Called immediately after the construction.
* This is a separate method so that code executed from here will see a valid value in
......@@ -496,7 +504,11 @@ public abstract class PluginManager extends AbstractModelObject {
public boolean isPluginUploaded() {
return pluginUploaded;
}
/**
* All discovered plugins.
*/
@Exported
public List<PluginWrapper> getPlugins() {
return plugins;
}
......
......@@ -25,6 +25,7 @@
package hudson;
import hudson.PluginManager.PluginInstanceStore;
import hudson.model.Api;
import jenkins.YesNoMaybe;
import jenkins.model.Jenkins;
import hudson.model.UpdateCenter;
......@@ -46,6 +47,8 @@ import static java.util.logging.Level.WARNING;
import org.apache.commons.logging.LogFactory;
import org.kohsuke.stapler.HttpResponse;
import org.kohsuke.stapler.HttpResponses;
import org.kohsuke.stapler.export.Exported;
import org.kohsuke.stapler.export.ExportedBean;
import java.util.Enumeration;
import java.util.jar.JarFile;
......@@ -72,6 +75,7 @@ import java.util.jar.JarFile;
*
* @author Kohsuke Kawaguchi
*/
@ExportedBean
public class PluginWrapper implements Comparable<PluginWrapper> {
/**
* {@link PluginManager} to which this belongs to.
......@@ -136,9 +140,13 @@ public class PluginWrapper implements Comparable<PluginWrapper> {
*/
/*package*/ boolean isBundled;
static final class Dependency {
@ExportedBean
public static final class Dependency {
@Exported
public final String shortName;
@Exported
public final String version;
@Exported
public final boolean optional;
public Dependency(String s) {
......@@ -194,6 +202,10 @@ public class PluginWrapper implements Comparable<PluginWrapper> {
this.optionalDependencies = optionalDependencies;
}
public Api getApi() {
return new Api(this);
}
/**
* Returns the URL of the index page jelly script.
*/
......@@ -238,6 +250,7 @@ public class PluginWrapper implements Comparable<PluginWrapper> {
return n;
}
@Exported
public List<Dependency> getDependencies() {
return dependencies;
}
......@@ -250,6 +263,7 @@ public class PluginWrapper implements Comparable<PluginWrapper> {
/**
* Returns the short name suitable for URL.
*/
@Exported
public String getShortName() {
return shortName;
}
......@@ -267,6 +281,7 @@ public class PluginWrapper implements Comparable<PluginWrapper> {
* null if this information is unavailable.
* @since 1.283
*/
@Exported
public String getUrl() {
// first look for the manifest entry. This is new in maven-hpi-plugin 1.30
String url = manifest.getMainAttributes().getValue("Url");
......@@ -289,6 +304,7 @@ public class PluginWrapper implements Comparable<PluginWrapper> {
/**
* Returns a one-line descriptive name of this plugin.
*/
@Exported
public String getLongName() {
String name = manifest.getMainAttributes().getValue("Long-Name");
if(name!=null) return name;
......@@ -298,6 +314,7 @@ public class PluginWrapper implements Comparable<PluginWrapper> {
/**
* Does this plugin supports dynamic loading?
*/
@Exported
public YesNoMaybe supportsDynamicLoad() {
String v = manifest.getMainAttributes().getValue("Support-Dynamic-Loading");
if (v==null) return YesNoMaybe.MAYBE;
......@@ -307,6 +324,7 @@ public class PluginWrapper implements Comparable<PluginWrapper> {
/**
* Returns the version number of this plugin
*/
@Exported
public String getVersion() {
String v = manifest.getMainAttributes().getValue("Plugin-Version");
if(v!=null) return v;
......@@ -382,6 +400,7 @@ public class PluginWrapper implements Comparable<PluginWrapper> {
/**
* Returns true if this plugin is enabled for this session.
*/
@Exported
public boolean isActive() {
return active && !hasCycleDependency();
}
......@@ -394,6 +413,7 @@ public class PluginWrapper implements Comparable<PluginWrapper> {
hasCycleDependency = hasCycle;
}
@Exported
public boolean isBundled() {
return isBundled;
}
......@@ -402,6 +422,7 @@ public class PluginWrapper implements Comparable<PluginWrapper> {
* If true, the plugin is going to be activated next time
* Jenkins runs.
*/
@Exported
public boolean isEnabled() {
return !disableFile.exists();
}
......@@ -482,10 +503,12 @@ public class PluginWrapper implements Comparable<PluginWrapper> {
* This method is conservative in the sense that if the version number is incomprehensible,
* it always returns false.
*/
@Exported
public boolean hasUpdate() {
return getUpdateInfo()!=null;
}
@Exported
public boolean isPinned() {
return pinFile.exists();
}
......@@ -500,6 +523,7 @@ public class PluginWrapper implements Comparable<PluginWrapper> {
/**
* returns true if backup of previous version of plugin exists
*/
@Exported
public boolean isDowngradable() {
return getBackupFile().exists();
}
......@@ -515,6 +539,7 @@ public class PluginWrapper implements Comparable<PluginWrapper> {
* returns the version of the backed up plugin,
* or null if there's no back up.
*/
@Exported
public String getBackupVersion() {
File backup = getBackupFile();
if (backup.exists()) {
......
......@@ -83,6 +83,8 @@ import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.acegisecurity.context.SecurityContextHolder;
import org.kohsuke.stapler.export.Exported;
import org.kohsuke.stapler.export.ExportedBean;
import org.kohsuke.stapler.interceptor.RequirePOST;
......@@ -101,6 +103,7 @@ import org.kohsuke.stapler.interceptor.RequirePOST;
* @author Kohsuke Kawaguchi
* @since 1.220
*/
@ExportedBean
public class UpdateCenter extends AbstractModelObject implements Saveable {
private static final String UPDATE_CENTER_URL = System.getProperty(UpdateCenter.class.getName()+".updateCenterUrl","http://updates.jenkins-ci.org/");
......@@ -142,6 +145,10 @@ public class UpdateCenter extends AbstractModelObject implements Saveable {
configure(new UpdateCenterConfiguration());
}
public Api getApi() {
return new Api(this);
}
/**
* Configures update center to get plugins/updates from alternate servers,
* and optionally using alternate strategies for downloading, installing
......@@ -162,6 +169,7 @@ public class UpdateCenter extends AbstractModelObject implements Saveable {
* @return
* can be empty but never null. Oldest entries first.
*/
@Exported
public List<UpdateCenterJob> getJobs() {
synchronized (jobs) {
return new ArrayList<UpdateCenterJob>(jobs);
......@@ -204,6 +212,7 @@ public class UpdateCenter extends AbstractModelObject implements Saveable {
* @return
* can be empty but never null.
*/
@Exported
public PersistedList<UpdateSite> getSites() {
return sites;
}
......@@ -748,6 +757,7 @@ public class UpdateCenter extends AbstractModelObject implements Saveable {
*
* This object will have the <tt>row.jelly</tt> which renders the job on UI.
*/
@ExportedBean
public abstract class UpdateCenterJob implements Runnable {
/**
* Which {@link UpdateSite} does this belong to?
......@@ -763,6 +773,10 @@ public class UpdateCenter extends AbstractModelObject implements Saveable {
this.site = site;
}
public Api getApi() {
return new Api(this);
}
/**
* @deprecated as of 1.326
* Use {@link #submit()} instead.
......@@ -771,6 +785,11 @@ public class UpdateCenter extends AbstractModelObject implements Saveable {
submit();
}
@Exported
public String getType() {
return getClass().getSimpleName();
}
/**
* Schedules this job for an execution
* @return
......@@ -782,6 +801,7 @@ public class UpdateCenter extends AbstractModelObject implements Saveable {
return installerService.submit(this,this);
}
@Exported
public Throwable getError() {
return error;
}
......@@ -794,11 +814,13 @@ public class UpdateCenter extends AbstractModelObject implements Saveable {
/**
* Unique ID that identifies this job.
*/
@Exported
public final int id = iota.incrementAndGet();
/**
* Immutable state of this job.
*/
@Exported(inline=true)
public volatile RestartJenkinsJobStatus status = new Pending();
/**
......@@ -829,15 +851,19 @@ public class UpdateCenter extends AbstractModelObject implements Saveable {
error = exception;
}
}
@ExportedBean
public abstract class RestartJenkinsJobStatus {
@Exported
public final int id = iota.incrementAndGet();
}
public class Pending extends RestartJenkinsJobStatus {
@Exported
public String getType() {
return getClass().getSimpleName();
}
}
public class Running extends RestartJenkinsJobStatus {
......@@ -912,10 +938,12 @@ public class UpdateCenter extends AbstractModelObject implements Saveable {
/**
* Unique ID that identifies this job.
*/
@Exported
public final int id = iota.incrementAndGet();
/**
* Immutable object representing the current state of this job.
*/
@Exported(inline=true)
public volatile InstallationStatus status = new Pending();
/**
......@@ -928,6 +956,7 @@ public class UpdateCenter extends AbstractModelObject implements Saveable {
*/
protected abstract File getDestination();
@Exported
public abstract String getName();
/**
......@@ -941,6 +970,7 @@ public class UpdateCenter extends AbstractModelObject implements Saveable {
/**
* Get the user that initiated this job
*/
@Exported
public Authentication getUser() {
return this.authentication;
}
......@@ -1002,9 +1032,14 @@ public class UpdateCenter extends AbstractModelObject implements Saveable {
*/
public abstract class InstallationStatus extends Throwable {
public final int id = iota.incrementAndGet();
@Exported
public boolean isSuccess() {
return false;
}
@Exported
public final String getType() {
return getClass().getSimpleName();
}
}
/**
......@@ -1076,6 +1111,7 @@ public class UpdateCenter extends AbstractModelObject implements Saveable {
/**
* What plugin are we trying to install?
*/
@Exported
public final Plugin plugin;
private final PluginManager pm = Jenkins.getInstance().getPluginManager();
......
......@@ -49,6 +49,8 @@ import org.kohsuke.stapler.HttpResponse;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.export.Exported;
import org.kohsuke.stapler.export.ExportedBean;
import javax.servlet.ServletContext;
import java.io.ByteArrayInputStream;
......@@ -533,23 +535,28 @@ public class UpdateSite {
}
}
@ExportedBean
public static class Entry {
/**
* {@link UpdateSite} ID.
*/
@Exported
public final String sourceId;
/**
* Artifact ID.
*/
@Exported
public final String name;
/**
* The version.
*/
@Exported
public final String version;
/**
* Download URL.
*/
@Exported
public final String url;
public Entry(String sourceId, JSONObject o) {
......@@ -577,12 +584,17 @@ public class UpdateSite {
}
}
public Api getApi() {
return new Api(this);
}
}
public final class Plugin extends Entry {
/**
* Optional URL to the Wiki page that discusses this plugin.
*/
@Exported
public final String wiki;
/**
* Human readable title of the plugin, taken from Wiki page.
......@@ -591,28 +603,34 @@ public class UpdateSite {
* <p>
* beware of XSS vulnerability since this data comes from Wiki
*/
@Exported
public final String title;
/**
* Optional excerpt string.
*/
@Exported
public final String excerpt;
/**
* Optional version # from which this plugin release is configuration-compatible.
*/
@Exported
public final String compatibleSinceVersion;
/**
* Version of Jenkins core this plugin was compiled against.
*/
@Exported
public final String requiredCore;
/**
* Categories for grouping plugins, taken from labels assigned to wiki page.
* Can be null.
*/
@Exported
public final String[] categories;
/**
* Dependencies of this plugin.
*/
@Exported
public final Map<String,String> dependencies = new HashMap<String,String>();
@DataBoundConstructor
......@@ -654,6 +672,7 @@ public class UpdateSite {
* If some version of this plugin is currently installed, return {@link PluginWrapper}.
* Otherwise null.
*/
@Exported
public PluginWrapper getInstalled() {
PluginManager pm = Jenkins.getInstance().getPluginManager();
return pm.getPlugin(name);
......@@ -666,6 +685,7 @@ public class UpdateSite {
* If it's not older, or it's not installed, or it's installed but there's no compatibleSinceVersion
* specified, it'll return true.
*/
@Exported
public boolean isCompatibleWithInstalledVersion() {
PluginWrapper installedVersion = getInstalled();
if (installedVersion != null) {
......@@ -682,6 +702,7 @@ public class UpdateSite {
/**
* Returns a list of dependent plugins which need to be installed or upgraded for this plugin to work.
*/
@Exported
public List<Plugin> getNeededDependencies() {
List<Plugin> deps = new ArrayList<Plugin>();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册