Working with Plugin UI
Generate UI with annotations
QuickBuild has a Bean Editor which is able to generate UI through annotations for below situations:
- View or edit steps.
- View or edit repositories.
- View or edit plugin settings.
Let's demonstrate this by enhancing myplugin to log the message supplied by user instead of just a hard coded "hello world". To do so, we create another class MyAnotherStep.java like below:
package com.example.myplugin;
import org.hibernate.validator.NotEmpty;
import com.pmease.quickbuild.Context;
import com.pmease.quickbuild.annotation.Editable;
import com.pmease.quickbuild.annotation.Scriptable;
import com.pmease.quickbuild.stepsupport.Step;
@Editable(category="examples", name="print message",
description="This step prints an user defined message into the build log.")
public class MyAnotherStep extends Step {
private static final long serialVersionUID = 1L;
private String message;
// UI annotations must be applied to the getter method
@Editable(order=100, name="Your Message", description="Specify your message here.")
@NotEmpty
@Scriptable
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public void run() {
// Make sure to call getters to access scriptable fields, otherwise,
// the enclosed script will not be executed
Context.getLogger().info(getMessage());
}
}
And modify MyPlugin.java to include this newly created step type as another extension:
package com.example.myplugin;
import com.pmease.quickbuild.extensionpoint.StepProvider;
import com.pmease.quickbuild.pluginsupport.AbstractPlugin;
import com.pmease.quickbuild.stepsupport.Step;
public class MyPlugin extends AbstractPlugin {
@Override
public Object[] getExtensions() {
return new Object[] {
new StepProvider() {
@Override
public Class<? extends Step> getStepClass() {
return MyStep.class;
}
},
new StepProvider() {
@Override
public Class<? extends Step> getStepClass() {
return MyAnotherStep.class;
}
}
};
}
}
Save these classes, and start QuickBuild from Eclipse. You should now be able to see a new step type print message in the examples category. Edit this step by adding it to build execution sequence. Below UI will be presented:
Run the build and your supplied message will be printed into build log.
Now let's look at annotations applied to method MyAnotherStep#getMessage():
- UI annotations must be applied to field's getter method.
- The annotation @Editable marks a field as editable and defines display name, order, and description of the field. These attributes are optional:
- If name is left empty, the field name will be used.
- If description is left empty, no description will be displayed when you edit the property.
- If order is left empty, a default value of MAX_INTEGER will be assumed.
- @NotEmpty is an optional constraint annotation telling QuickBuild that this field does not accept empty value.
- @Scriptable is optional and is normally applied to field of String type. It allows the field to make use of QuickBuild's scripting facility. For example, when define the print message step, you may specify the message as hello ${user.name} to say hello to current QuickBuild user. Scriptable field needs to be accessed through getter method; otherwise the embedded scripts will not be executed. Method MyAnotherStep.java#run() obeys this rule by executing Context.getLogger().info(getMessage()); instead of Context.getLogger().info(message);.
For more information on how to annotate classes to generate customized UI, please refer to Bean Editor.
Create UI with Wicket
QuickBuild uses Wicket as its presentation layer. If your plugin contributes tabs/panels to QuickBuild, you will need to have some knowledge of this framework. We demonstrate this by adding a new panel to build overview screen printing "hello world".
First create a class MyPanel.java like below:
package com.example.myplugin;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;
import com.pmease.quickbuild.Context;
public class MyPanel extends Panel {
private static final long serialVersionUID = 1L;
public MyPanel(String id) {
super(id);
String userName;
if (Context.getUser() != null)
userName = Context.getUser().getName();
else
userName = "guest";
add(new Label("message", "hello " + userName));
}
}
And add its html template MyPanel.html like below:
<wicket:panel>
<div wicket:id="message" class="round-corner" style="padding:16px;"/>
</wicket:panel>
Finally modify MyPlugin.java to implement extension point BuildOverviewContribution:
package com.example.myplugin;
import java.util.ArrayList;
import java.util.List;
import org.apache.wicket.markup.html.panel.Panel;
import com.pmease.quickbuild.extensionpoint.BuildOverviewContribution;
import com.pmease.quickbuild.extensionpoint.StepProvider;
import com.pmease.quickbuild.extensionpoint.support.PanelCreator;
import com.pmease.quickbuild.pluginsupport.AbstractPlugin;
import com.pmease.quickbuild.stepsupport.Step;
public class MyPlugin extends AbstractPlugin {
@Override
public Object[] getExtensions() {
return new Object[] {
new StepProvider() {
@Override
public Class<? extends Step> getStepClass() {
return MyStep.class;
}
},
new StepProvider() {
@Override
public Class<? extends Step> getStepClass() {
return MyAnotherStep.class;
}
},
new BuildOverviewContribution() {
public List<PanelCreator> getPanelCreators() {
List<PanelCreator> creators = new ArrayList<PanelCreator>();
creators.add(new PanelCreator() {
public Panel getPanel(String id) {
return new MyPanel(id);
}
});
return creators;
}
public int getOrder() {
return 500;
}
}
};
}
}
Start QuickBuild and switch to build overview screen, you will see a new panel saying hello to current user.
For more details of creating plugin UI with Wicket, refer to plugin com.pmease.quickbuild.plugin.sample.javancss in Plugin Examples.