Introduction to Multilingual Retrieval Augmented Generation (RAG)
Owner - Java properties reinvented.
1. OWNER
Java™ properties reinvented.
Get rid of the boilerplate code in properties based configuration.
!
http://owner.aeonbits.org
Luigi R. Viggiano
luigi.viggiano@gmail.com
2. About this presentation
WARNING:
Viewer discretion is advised
This presentation contains source code.
Non technical people may experience confusional states, dizziness, sleepiness and fainting.
The author is not good in putting colors together.
3. In a nutshell
•
OWNER's goal is to minimize the code required for
properties based configuration in Java applications.
•
An open source (BSD License) Java library.
•
Artifacts are available on Maven Central Repository
•
Source code is managed on GitHub (24 forks and 111 stars).
•
Inspired on how GWT i18n manages translations on client
side.
•
Requires Java 5 or newer.
•
No dependencies on 3rd party libraries.
4. Why?
Programmers are left to do many tasks on their own
when using java.util.Properties
It requires a lot of code. Repetitive code.
5. What?
What are the very basic things needed to handle properties
files?
•
load the file (from the filesystem? from the classpath?)
•
define a configuration object that exposes its settings via
convenient business methods.
•
do the conversion (boolean, int, URLs, Files, Objects…).
•
define default values when not specified in the file.
•
etc…
6. How?
How OWNER do its stuff without being repetitive?
1. Imagine you have a Properties file ‘ServerConfig.properties’ in a given java
package:
!
!
2. Define a class named the same way ‘ServerConfig.java’:
!
!
!
7. How?
How OWNER do its stuff without being repetitive?
3. Use it!
!
!
Since the properties file does have the same name as the Java class, and
they are located in the same package, OWNER will be able to associate
them.
The properties names defined in the properties file will be associated to
the methods in the Java class having the same name.
8. Principles
“Simple things should be simple,
complex things should be possible.”
-- Alan Kay (Computer Scientist)
•
Things should be as much simple as they can be.
New/advanced features should not complicate the
basic usages.
•
Convention over configuration.
Require as less code as possible.
•
Use of annotations to customize the default behavior.
9. Goals
•
Be fully documented.
See: http://owner.aeonbits.org/
•
Be stable. OWNER is fully tested, development follows TDD
approach. Test coverage is currently 97%
See: https://coveralls.io/r/lviggiano/owner
•
Be feature rich.
See: http://owner.aeonbits.org/docs/features/
•
Don’t narrow the possibilities to the end user. The user should
be able to do with OWNER everything that he is already doing
with java.util.Properties. And more, of course.
10. Features Overview
•
Powerful Type Conversion; supports collections, primitives,
common Java objects and user defined objects.
•
Loading properties from multiple resources.
•
Two different “Loading Strategies”: load the FIRST
resource, MERGE all the available resources.
•
Importing (wrap) existing properties objects, as well as
system properties and environment variables.
•
Variables Expansion via the ${variable}notation.
11. Features Overview
•
Hot Reload and programmable reload.
•
Event notification. On reload, and on property change. With
some basic validation mechanism.
•
“Accessible” and “Mutable” interface to add capabilities to
access or change a Config object.
•
Debugging facilities.
•
Multiple formats: XML and Properties files support; user can
implement and configure custom loader for more file formats.
13. Type Conversion
The return type on the Configuration interface determines
how to convert the property value (String) to user’s specified
type. OWNER support primitive types, enumerations …
19. Type Conversion
To recap, all the types supported by OWNER for conversion:
1. Primitive types: boolean, byte, short, integer, long,
float, double.
2. Enums (notice that the conversion is case sensitive, so FOO !=
foo or Foo).
3. java.lang.String, of course (no conversion is needed).
4. java.net.URL, java.net.URI.
5. java.io.File (the character ~ will be expanded to user.home
System Property).
6. java.lang.Class (this can be useful, for instance, if you want
to load the jdbc driver, or similar cases).
20. Type Conversion
7. Any instantiable class declaring a public constructor with a single
argument of type java.lang.String.
8. Any instantiable class declaring a public constructor with a single
argument of type java.lang.Object.
9. Any class declaring a public static method
valueOf(java.lang.String) that returns an instance of itself.
10. Any class for which you can register a PropertyEditor via
PropertyEditorManager.registerEditor(). (See PropertyEditorTest
as an example).
11. Any array having above types as elements.
12. Any object that can be instantiated via @ConverterClass annotation
explained before.
13. Any Java Collections of all above types: Set, List, SortedSet or
concrete implementations like LinkedHashSet or user defined
collections having a default no-arg constructor. Map and sub-interfaces
are not supported (yet).
21. Loading Strategies
Common utilities (especially in unix) allow multiple
configuration files.
Tipically a System Level configuration located in
/etc/myapp.conf
and a User Level configuration located in
~/.myapp.conf
an example is the git scm command line tool.
22. Loading Strategies
A User Level configuration may totally override the
configuration at System Level, or may just redefine some
options. Example:
Repository Level Configuration overrides user level configuration
23. Loading Strategies
OWNER allows configuration overriding in 2 different way.
The “Load FIRST” approach (LoadType.FIRST):
Only the first available resource is loaded. Others are ignored.
24. Loading Strategies
OWNER allows configuration overriding in 2 different way.
The “Load MERGE” approach (LoadType.MERGE):
The actual configuration is the result of the merge between
all the specified resources. Topmost configuration
resources redefine properties in lowest resources.
25. Loading Strategies
@Sources annotation supports variable expansion:
•
file:${user.home}/.myapp.config (system property)
•
file:${HOME}/.myapp.config (environment variable)
•
file:~/.myapp.config (the ‘~’ literal accepted by bash)
Above examples are equivalent.
27. Loading Strategies
@Sources annotation can also expand variables
specified programmatically:
The ConfigFactory can accept configuration
properties itself. I call this “Metaconfiguring”
29. Importing Properties
You can specify multiple properties to import on the
same line:
!
If there are prop1 and prop2 defining two different values
for the same property key, the one specified first will
prevail.
31. Variable Expansion
Sometimes it may be useful to expand properties values
from other properties.
The property story() will expand to:
“The quick brown fox jumped over the lazy dog”
33. Reload and Hot Reload
Reloading configuration resources programmatically:
34. Reload and Hot Reload
Automatic “Hot Reload”
Hot Reload works fine with following URLs:
• file:path/to/your.properties filesystem backed URL
• jar:file:path/to/some.jar!/path/to/your.properties
a jar file in your local filesystem that contains a properties files.
• classpath:path/to/your.properties a resource loaded
from the classpath, if the classpath resource is stored on
filesystem (from inside a jar or from inside a classpath folder).
35. Reload and Hot Reload
The “Hot Reload” annotation definition:
36. Reload and Hot Reload
“Hot Reload” can be synchronous (HotReloadType.SYNC)…
37. Reload and Hot Reload
…or asynchronous (HotReloadType.ASYNC)…
39. Interfaces Tree
•
•
•
•
Config (is a marker interface).
Reloadable defines methods to programmatically realod the
configuration and to attach ReloadListeners
Accessible define methods to access internal properties values,
and to save/dump to OutputStream or Writer
Mutable defines methods to change properties values
programmatically and attach PropertyChangeListeners
43. Debugging Facilities
In your mapping interfaces you can optionally define one of
the following methods that may be convenient for
debugging:
44. XML Support
The java.util.Properties class supports an XML
format that looks like this:
…a fantastic* facility compared to the plain textual format of
properties files, uh?
The * means “I’m ironic”
45. XML Support
OWNER supports the previous XML format for properties
as well as any XML that can be possible mapped to a
properties list. Example:
The developer is free to use tags and attributes to define
properties names. Better now?
46. XML Support
Q: How to load the XML into the
Config object?
A: Simple: in the same way as you already do for properties file.
1. Suppose you have a mapping interface class in a source file
called foo.bar.ServerConfig.java, just place a resource in
your classpath in foo.bar.ServerConfig.xml.
2. Or you can specify the @Sources annotation with an URL
pointing to an file.xml. OWNER will notice the .xml extension
and will load the configuration source as XML.
47. User defined file formats
If you want to support your own file format, you can
register your loader in the ConfigFactory. Example:
ConfigFactory.registerLoader(new YamlLoader());
XML and Properties file format are in fact internally
implemented in this way. More file formats support are
planned for future releases.
48. Parameter Formatting
This comes directly from the GWT i18n:
Not really related to configuration. Maybe I should drop
this feature in favor of something better? The parameter
could have been used for different purpose (i.e. a type
safe setter method)
49. Disabling unwanted features
Variables expansion and parameters formatting can be
inconvenient if you have your own mechanisms. If for
any reason you want to disable it, on class level or
method level, you can use @DisableFeature annotation.