Digital Edition

SYS-CON.TV
Enabling Constant Substitution in Property Values
Enabling Constant Substitution in Property Values

XProperties is a simple subclass of java.util.Properties that allows you to treat property values like constants, referring to and embedding them inside other property values. It handles the substitution of the constant value automatically and transparently when you call the getProperty() method.

Using constants in your property files can make them easier to read and maintain. This article describes an extension to the properties facility in Java that greatly enhances its functionality and usefulness. Like many other Java programmers I use the Properties class extensively for managing configuration information. In an application I recently developed, I had several properties (database URLs) in a configuration property file that shared the same value. I wanted a way to specify a constant in a property file rather than repeating the same value over and over.

My first approach was to add some extra logic where I read in the properties. I designated constant values by an arbitrary prefix ($). As I accessed a property value, I checked if it began with the prefix and, if so, performed the substitution with the named constant value.

I soon realized, however, that I could generalize this capability by moving the logic into a subclass of java.util.Properties. I could also greatly increase its usefulness by not limiting it to a simple, single substitution. Rather, I allowed a constant value to be embedded anywhere within the property value, even allowing multiple constants within the same value. I chose to indicate constant names by enclosing them in braces, abandoning the single prefix character. This makes the constant names obvious and unambiguous, as well as easier to parse.

The following properties illustrate the use of a constant within a property value:

SOURCE = SampleApp
ErrorMessage = {SOURCE}: An error has occurred

The SOURCE property defines a constant value that's embedded within the value of the ErrorMessage property. As I mentioned earlier, to indicate that you wish to substitute the value of another property, surround its name with braces. Notice that the SOURCE property is defined just like any other property value. The only thing that makes it a "constant" is that it's referenced by another value. I've used all capital letters for the constant value, as is the convention in Java, but this is by no means a requirement. If the property name within the braces isn't found, then no substitution is performed and the property value is returned without modification.

You can substitute a constant anywhere in the property value, and even have more than one constant within a value, as in the following example:

CONST_1 = shoes and ships
CONST_2 = sealing wax
SomeValue = {CONST_1} and {CONST_2}
In this example, the "SomeValue" property evaluates to "shoes and ships and sealing wax."

Using constants within property values is especially useful when the same value occurs in multiple places, or when you build up a complex value from several reusable parts (e.g., file pathnames or URLs). Using constants also allows you to enumerate and assign descriptive names to potential property values. You may have to switch frequently between values for a property while developing a system, for instance, the URLs for unit test, system test, and production. One approach I've used is to include a property assignment for each possible value, but comment out the ones not being used. For example:

# MyURL = http://localhost:8080/abc
# MyURL = http://testserver.acme.com/abc
MyURL= http://prodserver.acme.com/abc
Without extra comments within the property file, however, it's unclear what each alternative represents. The extra commented lines also clutter the file, making it harder to read. Instead, by defining each alternative as a named constant, you can assign descriptive names to all the values, making the property files easier to understand, and also lessen the chance of making errors when switching between values. For instance, you can define:

UNIT_TEST_URL = http://localhost:8080/abc
SYSTEM_TEST_URL =
http://testserver.acme.com/abc
PRODUCTION_URL=http://prodserver.acme.com/abc
MyURL = {UNIT_TEST_URL}

In the above example, it's self-evident that the "MyURL" property is set to the value appropriate for the unit test environment. This example is included with several others in the sample property file shown in Listing 1. It illustrates some different ways to use constants within property values. Listing 2 contains Java source code to read in and access that property file using the XProperties class. Listing 3 shows the resulting output from running the code in Listing 2.

Note that the syntax for using the XProperties class - creating an XProperties object, loading the properties from a file, and accessing the property values - is exactly the same as for the java.util.Properties class. This demonstrates the power of inheritance. The XProperties class is designed to be a drop-in replacement for java.util.Properties. No changes or additions are made to the public API of the superclass. The XProperties class handles the constant substitution under the covers when you access a property value using the getProperty() method.

Another point to note is that you can nest the constant substitution to an arbitrary level. The XProperties class recursively evaluates each referenced constant. In Listing 1, the value of the property "MyHtmlFile" includes the value of the property "HTML_DIR". This, in turn, references the value of property "BASE_DIR", which then references "ROOT_DRIVE". You can see in Listing 3 that the value of "MyHtmlFile" evaluates to "c:/base/html/MyFile.html", incorporating all the constants used along the way.

Listing 4 contains the source code for the XProperties class. As you can see, it's not very complicated. The XProperties class overrides the getProperty(String) method. Handling the recursive substitution presented a minor challenge. How do you prevent an infinite recursive loop, as in the following example?

A={B}
B={A}

One option is to perform a complicated analysis to detect loops in the substitution tree. I chose a simpler approach. The XProperties class keeps track of the current depth of substitution (starts at zero and increments with each recursive substitution), and only allows up to an arbitrary (but easily changed) maximum depth - currently five. This logic is implemented in the private getProperty(String,int) method. This method performs the parsing and constant substitution, handles recursive invocation, if necessary, and checks the maximum substitution depth.

Like its superclass, the XProperties class includes a constructor that takes an existing properties object. These are default properties that are searched if a property key isn't found in the original property list. One use for this capability is to define a separate property file containing common constants that can then be accessed from multiple property files. All you need to do is load the property file containing the constants into a properties (or XProperties) object and then pass this object as the parameter to the XProperties constructor.

Be aware that the Properties.list(..) methods don't use the getProperty() method, and so don't perform any constant substitution before displaying property values.

Property files, like programs, can benefit from defining and using constants. You can specify a value once, and then reuse the same value for multiple properties, or you can have property values that are composed of several (potentially reusable) parts. These capabilities can be especially useful in configuration property files in which you need to specify complex values, like file pathnames or resource URLs. You can also enumerate and assign descriptive names to potential values when you need to frequently switch between alternative values for a property, for example, switching between test and production database URLs. The implementation of the XProperties class is fairly simple, but it provides a very useful extension to the properties facility in Java.

About Chris Mair
Chris Mair is a senior consultant and software craftsman at IBM with 12 years experience in the financial sector. He is a certified Java Developer, and specializes in object oriented design and development, frameworks, and J2EE.

In order to post a comment you need to be registered and logged in.

Register | Sign-in

Reader Feedback: Page 1 of 1



ADS BY GOOGLE
Subscribe to the World's Most Powerful Newsletters

ADS BY GOOGLE

ChatOps is an emerging topic that has led to the wide availability of integrations between group cha...
In his keynote at 18th Cloud Expo, Andrew Keys, Co-Founder of ConsenSys Enterprise, provided an over...
The cloud era has reached the stage where it is no longer a question of whether a company should mig...
You know you need the cloud, but you’re hesitant to simply dump everything at Amazon since you know ...
Coca-Cola’s Google powered digital signage system lays the groundwork for a more valuable connection...
In his session at 21st Cloud Expo, Raju Shreewastava, founder of Big Data Trunk, provided a fun and ...
The need for greater agility and scalability necessitated the digital transformation in the form of ...
As DevOps methodologies expand their reach across the enterprise, organizations face the daunting ch...
While some developers care passionately about how data centers and clouds are architected, for most,...
"Since we launched LinuxONE we learned a lot from our customers. More than anything what they respon...
Is advanced scheduling in Kubernetes achievable?Yes, however, how do you properly accommodate every ...
DevOps is under attack because developers don’t want to mess with infrastructure. They will happily ...
"As we've gone out into the public cloud we've seen that over time we may have lost a few things - w...
In his session at 21st Cloud Expo, Michael Burley, a Senior Business Development Executive in IT Ser...
Sanjeev Sharma Joins June 5-7, 2018 @DevOpsSummit at @Cloud Expo New York Faculty. Sanjeev Sharma is...
We are given a desktop platform with Java 8 or Java 9 installed and seek to find a way to deploy hig...
"I focus on what we are calling CAST Highlight, which is our SaaS application portfolio analysis too...
"Cloud4U builds software services that help people build DevOps platforms for cloud-based software a...
The question before companies today is not whether to become intelligent, it’s a question of how and...
Kubernetes is an open source system for automating deployment, scaling, and management of containeri...