Search code examples
javajenkinsjelly

Jenkins: Using validateButton on a class without Descriptor


I have a hudson.model.ManagementLink (which creates a page which can be accessed via Manage Jenkins.

I have some form fields which I'd like to validate using the f:validateButton. If this were to be done on say the config.jelly page of a Publisher (which has a descriptor) a simple doXXX() method would work in the descriptor.

If I add a similar doXXX() method directly to hudson.model.ManagementLink it is in fact accessible directly via the URL myPage/myMethod however the f:validateButton just returns a 404 and obviously I need to send the form values.

One potential solution I've come accross is withCustomDescriptorByName and have the logic in a descriptor I have elsewhere, but I can't get that to work.


Solution

  • To answer the actual question above (i.e. no descriptor), you can supply any fields needed for validation to the with attribute of f:validateButton (comma separated) then set the method attribute to something like the following...

    method="${it.fullURL}triggerOfficial"
    

    ... then in the java (it) there's a method...

    public String getFullURL(){
        return Stapler.getCurrentRequest().getOriginalRequestURI().substring(1);
    }
    

    ...then also the method to perform the validation itself...

    public FormValidation doTriggerOfficial() { 
        return FormValidation.ok("hello");
    }
    

    However, if you want to perform normal field validation (without a validateButton) on a class type which doesn't normally have a descriptor...

    1) Add implements Describable<YourClassName> to your class signature

    2) Add something like this...

    @SuppressWarnings("unchecked")
    @Override
    public Descriptor<ConfigLink> getDescriptor() {
        Jenkins jenkins = Jenkins.getInstance();
        if (jenkins == null) {
            throw new IllegalStateException("Jenkins has not been started");
        }
        return jenkins.getDescriptorOrDie(getClass());
    }
    

    3) Plus an inner class (with the normal doCheckXXX methods)

    @Extension
    public static final class DescriptorImpl extends Descriptor<YourClassName> {...}
    

    4) Then finally to link it in the jelly add attribute descriptor="${it.descriptor}" to the f:form tag containing your form elements you want to have auto-validated (this will invoke the getDescriptor detailed in step 2)