Injecting configuration

Tubing provides an annotation which you can use to inject configuration properties in any Tubing bean.

Basic setup

If you only have the default configuration file, called config.yml there is no special configuration that you need to do. You can use the @ConfigProperty annotation to inject any property. For example given following configuration:

broadcast-prefix: "[BROADCAST] >> "
cooldown-time: 60

Option 1: separate configuration bean

@IocBean
public class Configuration {

    @ConfigProperty("broadcast-prefix")
    public String broadcastPrefix;
    @ConfigProperty("cooldown-time")
    public int cooldownTime;
}

And inject the Configuration bean where you need it:

@IocBukkitListener
public class GuiBroadcaster implements Listener {


    private final MessageService messageService;
    private final Configuration configuration;

    public GuiBroadcaster(MessageService messageService, Configuration configuration) {
        this.messageService = messageService;
        this.configuration = configuration;
    }

    @EventHandler
    public void handleBroadcastEvent(MessageBroadcastedEvent messageBroadcastedEvent) {
        String message = messageBroadcastedEvent.getBroadcastedMessage().getMessage();
        Bukkit.getOnlinePlayers().forEach(p -> messageService.sendMessage(p, configuration.broadcastPrefix + message));
    }

}

Option 2: Inject property directly where needed

You don't need to create a special Configuration bean, you can also just inject the configuration property directly into the bean where you need it.

@IocBukkitListener
public class GuiBroadcaster implements Listener {

    @ConfigProperty("tubing-example.broadcast-prefix")
    private String broadcastPrefix;

    private final MessageService messageService;
    
    public GuiBroadcaster(MessageService messageService) {
        this.messageService = messageService;
    }

    @EventHandler
    public void handleBroadcastEvent(MessageBroadcastedEvent messageBroadcastedEvent) {
        String message = messageBroadcastedEvent.getBroadcastedMessage().getMessage();
        Bukkit.getOnlinePlayers().forEach(p -> messageService.sendMessage(p, broadcastPrefix + message));
    }

}

Multiple configuration files

Often with larger plugins you might have multiple configuration files to keep things tidy.

When we do have other configuration files we need to tell plugin the we do have multiple configuration files. This can be done by creating a TubingConfigurationProvider bean.

@IocBean
public class ExampleConfigurationProvider implements TubingConfigurationProvider {
    @Override
    public List<ConfigMigrator> getConfigurationMigrators() {
        return Collections.emptyList();
    }

    @Override
    public List<ConfigurationFile> getConfigurationFiles() {
        return Arrays.asList(
            new ConfigurationFile("config.yml"),
            new ConfigurationFile("configuration/databaseConfig.yml", "database")
        );
    }
}

In the above example I load in 2 configuration files. One is the default config.yml file, the other is a separate configuration file for all database related properties, called databaseConfig.yml. The second parameter of the ConfigurationFile constructor is the key of the config file. The key is important because this key will be later on used when we want to inject the property.

This is the only thing that you need to do to setup multiple configuration files. When injecting the config property we can use the earlier defined key as prefix.

databaseConfig.yml

host: 'myhost.com'
port: 3306
username: 'myuser'
password: 'mypass'
database-name: 'tubingexample'
@IocBean
public class DatabaseConfiguration {

    @ConfigProperty("database:host")
    public String host;
    @ConfigProperty("database:port")
    public int port;
    @ConfigProperty("database:username")
    public String username;
    @ConfigProperty("database:password")
    public String password;
    @ConfigProperty("database:database-name")
    public String databaseName;
    
}

Configuration transformer

We often have a bit more complex configuration types. The @ConfigProperty annotation can automatically map simple values like Strings, primitive types and enums, and simple lists. If we need something more complex we can define a transformer. A transformer is a class which will take the value from the FileConfiguration class and transform it into something else. Tubing will inject the result of the transformer into the bean.

Example:

Config.yml

# comma separated list
tubing-comma-split: yes,no,maybe

Transformer

The transformer must implement the IConfigTransformer interface. Basically this is just a mapper. The below example will simple take the value from the config file and split the String value by commas, and return the list.

public class CommaListTransformer implements IConfigTransformer<List<String>, String> {
    @Override
    public List<String> mapConfig(String value) {
        // split the config value by commas
        return Arrays.asList(value.split("\\s*,\\s*"));
    }
}

Now we can Inject this list into our bean like this:

@ConfigProperty("tubing-comma-split")
@ConfigTransformer(CommaListTransformer .class)
public List<String> commaSeparatedValues;

Tubing will use the transformer and inject the result value

Configuration placeholders

In Tubing it's possible to reference other properties in your property value by using the {{}} notation.

For example:

messages:
    some-prefix: "SomePrefix >>"
    example: "{{messages.some-prefix}} My cool message here" 

Last updated