# sabot **Repository Path**: mirrors_tomitribe/sabot ## Basic Information - **Project Name**: sabot - **Description**: Environment-aware CDI-based Configuration - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-09-26 - **Last Updated**: 2026-02-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README = Sabot :showtitle: "`A sabot /ˈsæboʊ/ is a device used in a firearm or cannon to fire a projectile, such as a bullet, that is smaller than the bore diameter, or which must be held in a precise position.`" Sabot is an environment-aware CDI Extension used to fire configuration into your applications with extreme precision. It also happens to be the name of the awesome CDI spec-lead, https://twitter.com/antoine_sd[Antoine Sabot-Durand], who wrote the core code this small project is based upon. Future revisions may be donated or merged in with http://tamaya.incubator.apache.org/[Apache Tamaya]. Java EE 6 or higher required. Optional dependency on Apache TomEE 1.0 or higher. == @Inject @Config The core concept is configuration data can be injected into your applications via `@Inject` with a simple `@Config` qualifier that names a property whose value you require. The Properties themselves can come from `java.lang.System.getProperties()` using -D[property name]=[property value] on the command line, properties added to a `WEB-INF/classes/base.properties` file or (optionally for TomEE users) in the `conf/system.properties` file of your server. [source,java] ---- @Inject @Config(value = "greeting") private String greeting; @Inject @Config(value = "color", defaultValue = "orange") private String color; @Inject @Config(value = "base", defaultValue = "${user.dir}") private File userDir; @Inject @Config(value = "home", defaultValue = "${user.home}") private File defaultFile; @Inject @Config(value = "service.timeout", defaultValue = "2 hours and 54 minutes") private Duration timeout; @Inject @Config(value = "service.enabled", defaultValue = "false") private Boolean enabled; @Inject @Config(value = "tx.retry") private Integer retry; [source] ---- == Custom Configuration There are various ways of customizing the configuration for differing environments. You can: * Add a 'test.properties' file to your test resources to override values found in the 'base.properties' file. * Add additional property file names via the System property 'org.tomitribe.sabot.environment' (Constant ConfigurationResolver.ENVIRONMENT) ** -Dorg.tomitribe.sabot.environment=prod,dev - Sabot would then load the 'prod.properties' and 'dev.properties' files in that order. * Create a configuration observer and add to to the classpath - You can use the TomEEConfiguration.java as your starting point. [source,java] ---- @Singleton public class YourConfiguration implements ConfigurationObserver { static { //This must occur before anything is initialized ConfigurationResolver.registerConfigurationObserver(new YourConfiguration()); } .... @Override public void mergeConfiguration(final Properties resolved) { ....[merge or override the configuration] } ---- == Custom Java Types Sabot does *not* use `java.beans.PropertyEditor` implementations by default like other String-to-Java libraries do. After 20 years of Java's existence, it's safe to say two styles dominate converting a `String` into a Java object: * A *Constructor* that take a single String as an argument. Examples: ** `java.io.File(String)` ** `java.lang.Integer(String)` ** `java.net.URL(String)` * A *static method* that returns an instance of the same class. Examples: ** `java.util.regex.Pattern.compile(String)` ** `java.net.URI.create(String)` ** `java.util.concurrent.TimeUnit.valueOf(String)` Use either of these conventions and Sabot will have no problem instantiating your object with the user-supplied `String` from the command-line args. This should cover *95%* of all cases, but in the event it does not, you can create a `java.beans.PropertyEditor` and register it with the JVM. Use your Google-fu to learn how to do that. The order of precedence is as follows: 1. Constructor 2. Static method 3. `java.beans.PropertyEditor`