Work In Progress
This documentation is in beta. It's missing lots of content, search is broken, and many links go nowhere. These problems will be fixed before release, but there's plenty of work left!
Skip to main content

Formats

This framework supports pluggable file formats and message formats, which allows your projects to use whatever formats you feel work best for you.

All formats are loaded using service-loaders based on sweet-spi.

File Formats

File formats are represented by the FileFormat type, and allow the framework to load translations from different filetypes.

Bundled

The framework comes with built-in support for the following file formats:

  • Java Properties: .properties via the PropertiesFormat type.
  • YAML: .yml and .yaml via the YamlFormat type, based on the yaml resource bundle library.

Custom

All custom file formats must extend the FileFormat interface, and they must be annotated with the @ServiceProvider annotation from sweet-spi. The FileFormat interface defines a set of APIs that you'll need to implement.

abstract val identifiersType: Set<String>

This is a set of identifiers that are unique to this file format. Generally, this should be the file extensions used by this format, without the . prefix.

abstract val controlType: ResourceBundle.Control

The resource bundle control object used to load the translations from the given file type.

If you need to write your own, we suggest taking a look at how the yaml resource bundle library does it.

If your file format is implemented as an object, you'll also need to include an internal function named readResolve that returns the object, otherwise you won't be able to use it in your Gradle scripts. For example:

@ServiceProvider
object MyFormat : FileFormat {
override val identifiers: Set<String> = setOf("my")
override val control: ResourceBundle.Contol = MyControl

@Suppress("UnusedPrivateMember")
/** Required for Gradle support. **/
internal fun readResolve(): Any = MyFormat
}

Message Formats

Message formats are represented by the MessageFormat type, and allow the framework to load and format translations using different message and placeholder syntaxes.

Bundled

The framework comes with built-in support for the following message formats:

Custom

All custom message formats must extend the MessageFormat interface, and they must be annotated with the @ServiceProvider annotation from sweet-spi. The MessageFormat interface defines a set of APIs that you'll need to implement.

abstract val identifierType: Set<String>

This is an identifier that must be unique to this message format.

abstract formatNamed(...)Returns:String

Format the incoming string with the given locale and named placeholders.

If your message format doesn't support named placeholders, use error() to throw an exception.

Arguments
stringType: String

The incoming translation string to be formatted.

localeType: Locale

The locale used to retrieve the translation string, which should be used for formatting dates and other data.

placeholdersType: Map<String, Any?>

A map representing the named placeholders to replace, where the keys represent the placeholder names.

abstract formatOrdinal(...)Returns:String

Format the incoming string with the given locale and ordinal placeholders.

If your message format doesn't support ordinal placeholders, use error() to throw an exception.

Arguments
stringType: String

The incoming translation string to be formatted.

localeType: Locale

The locale used to retrieve the translation string, which should be used for formatting dates and other data.

placeholdersType: Array<Any?>

An array representing the ordinal placeholders to replace, which should be referred to by their index numbers.

If your message format is implemented as an object, you'll also need to include an internal function named readResolve that returns the object, otherwise you won't be able to use it in your Gradle scripts. For example:

@ServiceProvider
object MyFormat : MessageFormat {
override val identifier: String = "my"

override fun formatNamed(
string: String, locale: Locale, placeholders: Map<String, Any?>
): String = error("...")

override fun formatOrdinal(
string: String, locale: Locale, placeholders: Array<Any?>
): String = error("...")

@Suppress("UnusedPrivateMember")
/** Required for Gradle support. **/
internal fun readResolve(): Any = MyFormat
}