提交 2764d166 编写于 作者: K kohsuke

Adding a mechanism for plugins to contribute to the global configuration page directly.

git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@10642 71c3de6d-444a-0410-be80-ed276b4c234a
上级 3cfc2e4e
......@@ -758,6 +758,12 @@ public class Functions {
return buf.toString();
}
public static boolean hasView(Object it, String path) {
if(it==null) return false;
return it.getClass().getClassLoader().getResource(
it.getClass().getName().replace('.','/').replace('$','/')+'/'+path)!=null;
}
/**
* Can be used to check a checkbox by default.
* Used from views like {@code h.defaultToTrue(scm.useUpdate)}.
......
package hudson;
import hudson.model.Hudson;
import hudson.model.Descriptor;
import hudson.model.Descriptor.FormException;
import hudson.scm.SCM;
import hudson.tasks.Builder;
import hudson.tasks.Publisher;
......@@ -14,6 +16,8 @@ import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URL;
import net.sf.json.JSONObject;
/**
* Base class of Hudson plugin.
*
......@@ -31,6 +35,12 @@ import java.net.URL;
* views against your Plugin class, and those are visible in this URL, too.
*
* <p>
* {@link Plugin} can have an optional <tt>config.jelly</tt> page. If present,
* it will become a part of the system configuration page (http://server/hudson/configure).
* This is convenient for exposing/maintaining configuration that doesn't
* fit any {@link Descriptor}s.
*
* <p>
* Up until Hudson 1.150 or something, subclasses of {@link Plugin} required
* <tt>@plugin</tt> javadoc annotation, but that is no longer a requirement.
*
......@@ -41,8 +51,10 @@ public abstract class Plugin {
/**
* Set by the {@link PluginManager}.
* This points to the {@link PluginWrapper} that wraps
* this {@link Plugin} object.
*/
/*package*/ PluginWrapper wrapper;
/*package*/ transient PluginWrapper wrapper;
/**
* Called when a plugin is loaded to make the {@link ServletContext} object available to a plugin.
......@@ -101,6 +113,18 @@ public abstract class Plugin {
public void stop() throws Exception {
}
/**
* Handles the submission for the system configuration.
*
* <p>
* If this class defines <tt>config.jelly</tt> view, be sure to
* override this method and persists the submitted values accordingly.
*
* @since 1.233
*/
public void configure(JSONObject formData) throws IOException, ServletException, FormException {
}
/**
* This method serves static resources in the plugin under <tt>hudson/plugin/SHORTNAME</tt>.
*/
......
package hudson;
import net.sf.json.JSONObject;
import net.sf.json.JSONArray;
import org.kohsuke.stapler.Stapler;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
import java.io.IOException;
import java.util.List;
import java.util.Collections;
/**
* Obtains the structured form data from {@link StaplerRequest}.
......@@ -35,4 +38,30 @@ public class StructuredForm {
}
return o;
}
/**
* Retrieves the property of the given object and returns it as a list of {@link JSONObject}.
*
* <p>
* If the value doesn't exist, this method returns an empty list. If the value is
* a {@link JSONObject}, this method will return a singleton list. If it's a {@link JSONArray},
* the contents will be returned as a list.
*
* <p>
* Because of the way structured form submission work, this is convenient way of
* handling repeated multi-value entries.
*
* @since 1.233
*/
public static List<JSONObject> toList(JSONObject parent, String propertyName) {
Object v = parent.get(propertyName);
if(v==null)
return Collections.emptyList();
if(v instanceof JSONObject)
return Collections.singletonList((JSONObject)v);
if(v instanceof JSONArray)
return (JSONArray)v;
throw new IllegalArgumentException();
}
}
......@@ -68,7 +68,6 @@ import hudson.util.TextFile;
import hudson.util.XStream2;
import hudson.widgets.Widget;
import net.sf.json.JSONObject;
import net.sf.json.JSONArray;
import org.acegisecurity.AccessDeniedException;
import org.acegisecurity.Authentication;
import org.acegisecurity.GrantedAuthority;
......@@ -1554,6 +1553,9 @@ public final class Hudson extends View implements ItemGroup<TopLevelItem>, Node,
for( JobPropertyDescriptor d : Jobs.PROPERTIES )
result &= d.configure(req);
for( JSONObject o : StructuredForm.toList(json,"plugin"))
pluginManager.getPlugin(o.getString("name")).getPlugin().configure(o);
save();
if(result)
rsp.sendRedirect(req.getContextPath()+'/'); // go to the top page
......
......@@ -81,6 +81,18 @@
</s:entry>
</s:section>
<!-- list config pages from plugins, if any -->
<j:forEach var="p" items="${it.pluginManager.plugins}">
<j:if test="${h.hasView(p.plugin,'config.jelly')}">
<s:rowSet name="plugin">
<tr><td>
<input type="hidden" name="name" value="${p.shortName}"/>
</td></tr>
<st:include page="config.jelly" from="${p.plugin}" optional="true"/>
</s:rowSet>
</j:if>
</j:forEach>
<d:taglib uri="local">
<!-- display global config pages for the given descriptors -->
<d:tag name="globalConfig">
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册