The minimum requirement is to implement two classes, one for the service declaration and one for the implementation itself.
The sample is a dataset user service that simply displays a "hello" message, it can be launched from the action menu of a dataset:

The service implementation class must implement the interface UserService<DatasetEntitySelection>:
/**
* This service displays hello world!
*/
public class HelloWordService implements UserService<DatasetEntitySelection>
{
public HelloWordService()
{
}
@Override
public void setupDisplay(
UserServiceSetupDisplayContext<DatasetEntitySelection> aContext,
UserServiceDisplayConfigurator aConfigurator)
{
// Set bottom bar
UIButtonSpecNavigation closeButton = aConfigurator.newCloseButton();
closeButton.setDefaultButton(true);
aConfigurator.setLeftButtons(closeButton);
// Set content callback
aConfigurator.setContent(this::writeHelloWorld);
}
private void writeHelloWorld(
UserServicePaneContext aPaneContext,
UserServicePaneWriter aWriter)
{
// Display Hello World!
aWriter.add("<div ");
aWriter.addSafeAttribute("class", UICSSClasses.CONTAINER_WITH_TEXT_PADDING);
aWriter.add(">");
aWriter.add("Hello World!");
aWriter.add("</div>");
}
@Override
public void setupObjectContext(
UserServiceSetupObjectContext<DatasetEntitySelection> aContext,
UserServiceObjectContextBuilder aBuilder)
{
// No context yet.
}
@Override
public void validate(UserServiceValidateContext<DatasetEntitySelection> aContext)
{
// No custom validation is necessary.
}
@Override
public UserServiceEventOutcome processEventOutcome(
UserServiceProcessEventOutcomeContext<DatasetEntitySelection> aContext,
UserServiceEventOutcome anEventOutcome)
{
// By default do not modify the outcome.
return anEventOutcome;
}
}
The declaration class must implement the interface UserServiceDeclaration.OnDataset:
/**
* Declaration for service hello world!
*/
public class HelloWorldServiceDeclaration implements UserServiceDeclaration.OnDataset
{
// The service key identifies the user service.
private static final ServiceKey serviceKey = ServiceKey.forName("HelloWorld");
public HelloWorldServiceDeclaration()
{
}
@Override
public ServiceKey getServiceKey()
{
return serviceKey;
}
@Override
public UserService<DatasetEntitySelection> createUserService()
{
// Creates an instance of the user service.
return new HelloWordService();
}
@Override
public void defineActivation(ActivationContextOnDataset aContext)
{
// The service is activated for all datasets instanciated with
// the associated data model (see next example).
}
@Override
public void defineProperties(UserServicePropertiesDefinitionContext aContext)
{
// This label is displayed in menus that can execute the user service.
aContext.setLabel("Hello World Service");
}
@Override
public void declareWebComponent(WebComponentDeclarationContext aContext)
{
}
}
In this sample, the user service is registered by a data model. The data model needs to define a schema extension that implements the following code:
public class CustomSchemaExtensions implements SchemaExtensions
{
@Override
public void defineExtensions(SchemaExtensionsContext aContext)
{
// Register the service.
aContext.registerUserService(new HelloWorldServiceDeclaration());
}
}
For details on the declaration of schema extensions, see SchemaExtensions.