Habitat4J Example Index

Starter Examples Intermediate Examples Advanced Examples
Starter Example 1.0 - Preparing for Habitat4J

You will need the following ready prior to reading through and testing the following examples:

  • A name for your application, such as: MyApp
  • A name for your computer, such as: Local
  • A development environment for your computer, such as: Development
  • A place to put the computer-global Server Identity file, such as: c:/apps/server-identity.xml or /etc/apps/server-identity.xml.
  • The latest version of the Habitat4J jar on your classpath. The file is provided with the naming format: habitat4j-x.y.z.jar.
  • The log4j logger on your classpath (optional, see Enabling log4j Support in Habitat4J).
  • A Xerces XML implementation on your classpath.
  • A SAX XML parser implementation on your classpath.

Starter Example 1.1 - Creating and Deploying a Minimal Server-Identity XML File

The absolute bare minimum needed if there is no intention to use the contextual capability of Habitat4J is the following server-identity.xml:

<?xml version="1.0"?>
<server-identity/>

If deploying your code to a Microsoft Windows environment, the default location is the root folder of the drive your app server/test environment/IDE is running under. For most users, the likely location is c:\server-identity.xml.

If deploying your code to a Un*x environment, the default location is the root directory, i.e. /server-identity.xml.

To override this default, set your JVM "-D" property or execute a System.setProperty() prior to initializing Habitat4J. It is recommended that you place this file in a common area for use by all of your Java applications. For instance:

  System.setProperty(
    "org.productivity.java.habitat4j.serverIdentityFilePath",
    "c:/apps/server-identity.xml"
  );  

(or)

  System.setProperty(
    "org.productivity.java.habitat4j.serverIdentityFilePath",
    "/etc/apps/server-identity.xml"
  );  

Starter Example 1.2 - Creating a Simple Server-Identity XML File

The following simple server-identity.xml example is recommended to get started with Habitat4J:

<?xml version="1.0"?>
<server-identity>
  <application>
    <environment>Development</environment>
    <instance>
      <name>local</name>
      <description>Local Development Workstation</description>
      <enumeration>1</enumeration>
    </instance>
  </application>
</server-identity>

Please follow the same deployment instructions as noted in Starter Example 1.1.


Starter Example 1.3 - Creating and Using a Simple Property-List XML File

Start with the following property-list-1.3.xml example XML file:

<?xml version="1.0"?>
<property-list>
  <context>
    <property name="test.property.1">test.value.1</property>
    <property name="test.property.2">test.value.2</property>
  </context>
</property-list>

You can store this file anywhere in your filesystem, or in a classpath resource (see Intermediate Example x.y). For sake of this example, we'll place the file in c:/apps/myapp/property-list-1.3.xml.

Here's the code you'll need to retrieve these properties.

  // Do the following three lines once, when you application starts up
  // (commonly called the "bootstrap" initialization)

  // NOTE: The setProperty() call is not be necessary if you have placed the
  // server-identity.xml file in the default Habitat4J location, or if you've
  // used a JVM (-D) property entry.
  System.setProperty(
    "org.productivity.java.habitat4j.serverIdentityFilePath",
    "c:/apps/server-identity.xml"
  );  
  PropertyListManager.initialize("MyApp");
  PropertyListManager.loadPropertyListFromFile("c:/apps/myapp/property-list-1.3.xml");

  // Do this anywhere in your application  
  String testPropertyOne = PropertyListManager.getProperty("test.property.1");
  String testPropertyTwo = PropertyListManager.getProperty("test.property.2");

NOTE: By calling loadPropertyListFromFile() with one parameter, you're loading the "default" list. This list literally has the identifying name of default. All Property accessor methods are set up so that if you omit the identifying list name, you're accessing the default list. The next Starter Example shows how to use multiple lists beyond the default list.

NOTE: If you don't have the server-identity.xml or property-list-1.3.xml files deployed, the initialize() method call will not generate an exception, but the loadPropertyListFromFile() will generate a PropertyListHandlerException.


Starter Example 1.4 - Using Multiple Property-List XML Files

Here we define two files, property-list-1.4a.xml:

<?xml version="1.0"?>
<property-list>
  <context>
    <property name="test.property.a">test.value.a</property>
  </context>
</property-list>

...and property-list-1.4b.xml:

<?xml version="1.0"?>
<property-list>
  <context>
    <property name="test.property.b">test.value.b</property>
  </context>
</property-list>

Here's the code to access them:

  // [Insert bootstrap code in Starter Example 1.3]
  // Do the following during bootstrap
  PropertyListManager.loadPropertyListFromFile("listA","c:/apps/myapp/property-list-1.4a.xml");
  PropertyListManager.loadPropertyListFromFile("listB","c:/apps/myapp/property-list-1.4b.xml");
  
  // Do this anywhere in your application
  String testA = PropertyListManager.getProperty("listA","test.property.a");  
  String testB = PropertyListManager.getProperty("listB","test.property.b"); 

If you omit the first parameter to the getProperty() method, you'll be accessing the default list. For an example of loading the default list, see Starter Example 1.3.

RECOMMENDATION: If you plan to use multiple Property-Lists, it is suggested that you create global static definitions for your property names in lieu of repeating the String identifier. A single typo could result in a null entry where your application was expecting a value.


Starter Example 1.5 - Using a Property Array

Habitat4J allows you to store more than just name/value pairs. This example shows how to use a value array.

Here we define property-list-1.5.xml:

<?xml version="1.0"?>
<property-list>
  <context>
    <property-array name="test.property.array.english">
      <item>one</item>
      <item>two</item>
      <item>three</item>
    </property-array>
    <property-array name="test.property.array.spanish">
      <item>uno</item>
      <item>dos</item>
      <item>tres</item>
    </property-array>
  </context>
</property-list>

Here's the code:

  // [Insert bootstrap code in Starter Example 1.3]
  // Do the following during bootstrap
  PropertyListManager.loadPropertyListFromFile("language","c:/apps/myapp/property-list-1.5.xml");
  
  // Do this anywhere in your application
  String[] english = PropertyListManager.getPropertyArray("language","test.property.array.english");  
  String[] spanish = PropertyListManager.getPropertyArray("language","test.property.array.spanish");

Starter Example 1.6 - Using a Property Hash

Habitat4J allows you to store values in an easy-to-use Hashtable:

Here we define property-list-1.6.xml:

<?xml version="1.0"?>
<property-list>
  <context>
    <property-hash name="test.property.array.english">
      <item key="1">one</item>
      <item key="2">two</item>
      <item key="3">three</item>
    </property-hash>
    <property-hash name="test.property.array.spanish">
      <item key="one">uno</item>
      <item key="two">dos</item>
      <item key="three">tres</item>
    </property-hash>
  </context>
</property-list>

Here's the code:

  // [Insert bootstrap code in Starter Example 1.3]
  // Do the following during bootstrap
  PropertyListManager.loadPropertyListFromFile("language","c:/apps/myapp/property-list-1.6.xml");
  
  // Do this anywhere in your application
  PropertyHash english = PropertyListManager.getPropertyHash("language","test.property.array.english");  
  PropertyHash spanish = PropertyListManager.getPropertyHash("language","test.property.array.spanish");
  
  String one = (String) english.get("1");
  String tres = (String) spanish.get("three");

  // or, alternately, you can get the value directly (without the Hashtable) with this code:
  
  String oneAlt =
    PropertyListManager.getPropertyHashValue("languageProfileGroup","test.property.array.english","1");

  String tresAlt =
    PropertyListManager.getPropertyHashValue("languageProfileGroup","test.property.array.spanish","three");

Starter Example 1.7 - Using a Property Bean

Habitat4J also allows the use of a Javabean. First, you'll need to either use or create a Javabean -- which is simply a Java Object that implements a default constructor (public with no arguments) and fields accessible via "getter" and "setter" methods. For example, we'll use the following LanguageBean.java Class:

  // NOTE: The following bean is actually not implemented in Habitat4J.
  package org.productivity.org.java.habitat4j.example;

  public class LanguageBean {
    private String name = null;
    private String accent = null;
    private String type = null;
    
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

    public String getAccent() { return accent; }
    public void setAccent(String accent) { this.accent = accent; }

    public String getType() { return type; }
    public void setType(String type) { this.type = type; }
  }

Next, we'll need to define the Property-List property-list-1.7.xml:

<?xml version="1.0"?>
<property-list>
  <definitions>
    <property-bean id="language" class="org.productivity.org.java.habitat4j.example.LanguageBean"/>
  </definitions>
  <context>
    <property-bean name="test.property.bean.english.boston" id="language">
      <name>English</name>
      <accent>Boston</accent>
      <type>verbal</type>
    </property-bean>
    <property-bean name="test.property.bean.chinese.mandarin" id="language">
      <name>Chinese</name>
      <type>written</type>     
    </property-bean>
  </context>
</property-list>

As shown above, you need to set up a symbolic definition that specifies an id to be used to reference a bean of a certain class. This needs to be done only once per Property-List XML File. Then, when you define each value instance of property-bean, you need to reference the id so that Habitat4J knows which class object to instantiate.

Finally, here's the code:

  // [Insert bootstrap code in Starter Example 1.3]
  // Do the following during bootstrap
  PropertyListManager.loadPropertyListFromFile("languageProfiles","c:/apps/myapp/property-list-1.7.xml");
  
  // Do this anywhere in your application
  LanguageBean bostonBean =
    (LanguageBean) PropertyListManager.getPropertyBean("languageProfiles","test.property.bean.english.boston");  
  LanguageBean mandarinBean =
    (LanguageBean) PropertyListManager.getPropertyBean("languageProfiles","test.property.bean.chinese.mandarin");

The following bean parameter types are supported by Habitat4J:

Primitive Types
  • short
  • int
  • long
  • double
  • float
  • char
  • boolean
Object Types
  • Short
  • Integer
  • BigInteger
  • Long
  • Double
  • Float
  • BigDecimal
  • Character
  • Boolean
  • String

NOTE: You'll have to cast the return value of getPropertyBean().

NOTE: You can use more than one bean definition, as long as you choose a unique id.


Starter Example 1.8 - Using a Property Bean Array

Habitat4J can handle an array of instances of PropertyBean. Using the same class definition found in Starter Example 1.7, here's the Property-List property-list-1.8.xml:

<?xml version="1.0"?>
<property-list>
  <definitions>
    <property-bean id="language" class="org.productivity.org.java.habitat4j.example.LanguageBean"/>
  </definitions>
  <context>
    <property-bean-array name="test.property.bean.array" id="language">
      <item>
        <name>English</name>
        <accent>Boston</accent>
        <type>verbal</type>
      </item>
      <item>
        <name>Chinese</name>
        <type>written</type>     
      </item>
    </property-bean-array>
  </context>
</property-list>

Here's the code:

  // [Insert bootstrap code in Starter Example 1.3]
  // Do the following during bootstrap
  PropertyListManager.loadPropertyListFromFile("languageProfileGroup","c:/apps/myapp/property-list-1.6.xml");
  
  // Do this anywhere in your application
  LanguageBean[] languages = 
    (LanguageBean[]) PropertyListManager.getPropertyBeanArray("languageProfileGroup","test.property.bean.array");  

NOTE: You'll have to cast the return value of getPropertyBean(). Be sure to include the array identifier, or [].


Starter Example 1.9 - Using a Property Bean Hash

Habitat4J can handle a Hashtable of instances of PropertyBean. Using the same class definition found in Starter Example 1.7, here's the Property-List property-list-1.9.xml:

<?xml version="1.0"?>
<property-list>
  <definitions>
    <property-bean id="language" class="org.productivity.org.java.habitat4j.example.LanguageBean"/>
  </definitions>
  <context>
    <property-bean-hash name="test.property.bean.hash" id="language">
      <item key="en_us">
        <name>English</name>
        <accent>Boston</accent>
        <type>verbal</type>
      </item>
      <item key="zh_tw">
        <name>Chinese</name>
        <type>written</type>     
      </item>
    </property-bean-hash>
  </context>
</property-list>

Here's the code:

  // [Insert bootstrap code in Starter Example 1.3]
  // Do the following during bootstrap
  PropertyListManager.loadPropertyListFromFile("languageProfileGroup","c:/apps/myapp/property-list-1.6.xml");
  
  // Do this anywhere in your application
  PropertyHash languages = 
    PropertyListManager.getPropertyBeanHash("languageProfileGroup","test.property.bean.hash");
    
  LanguageBean english = (LanguageBean) languages.get("en_us");
  LanguageBean chinese = (LanguageBean) languages.get("zh_tw");
  
  // or, alternately, you can get the PropertyBean implementation directly with this code:
  
  LanguageBean englishAlt = (LanguageBean)
    PropertyListManager.getPropertyBeanHashValue("languageProfileGroup","test.property.bean.hash","en_us");

  LanguageBean chineseAlt = (LanguageBean)
    PropertyListManager.getPropertyBeanHashValue("languageProfileGroup","test.property.bean.hash","zh_tw");

NOTE: For the use of PropertyListManager.getPropertyHash(..), you'll have to cast the Hashtable get() return value.


Starter Example 1.10 - Setting System Properties

Habitat4J allows you to set System and Security properties. Here's the Property-List property-list-1.10.xml:

<?xml version="1.0"?>
<property-list>
  <context>
    <system-property name="system.property.1">system.property.value.1</system-property>
    <security-property name="security.property.1">security.property.value.1</security-property>
  </context>
</property-list>

No additional code is needed. This property will be set within the proper context. Habitat4J simply executes the System.setProperty() and Security.setProperty() methods.


Starter Example 1.11 - Using Built-In XSD Validation (Highly Recommended)

It is highly recommended that Habitat4J's XSD Validation feature is turned on, for both Server-Identity XML files as well as Property-List XML files. To do this, execute this code before loading the Property-List XML files:

  PropertyListManager.setFeature(Habitat4JFeatures.SERVER_IDENTITY_FEATURE_XSD_VALIDATION,true);
  PropertyListManager.setFeature(Habitat4JFeatures.PROPERTY_LIST_FEATURE_XSD_VALIDATION,true);

Intermediate Example 2.0 - Enabling log4j Support in Habitat4J

Habitat4J is set to log to System.out/System.err by default. You can also choose to use log4j.

First, in your code, perform the following:

Habitat4JLogger logger = Habitat4JLogger.getInstance();
logger.selectLog4j();

Then, include the following entries in your application's log4j.xml file:

  <appender name="Habitat4JConsole" class="org.apache.log4j.ConsoleAppender">
    <param name="Target" value="System.out"/>
    <param name="Threshold" value="DEBUG"/>

    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/>
    </layout>
  </appender>

  <appender name="Habitat4JAppender" class="org.apache.log4j.AsyncAppender">
    <appender-ref ref="Habitat4JConsole"/>
    </appender>

  <category name="org.productivity.java.habitat4j" additivity="false" >
    <priority value="INFO" />
    <appender-ref ref="Habitat4JAppender"/>
  </category>

If you're familiar with log4j, feel free to modify the above to point to a different appender.

NOTE: You can switch between System.out/System.err and log4j logging modes at any time during runtime. Use the logger.selectSystem() method to put Habitat4J back into the System.out/System.err logging mode.


Advanced Example 3.0 - Avoiding the Server-Identity XML File: JVM

Although it is highly recommended that a Server-Identity XML file be used to define your application's context, you can initialize the Habitat4J Server-Identity object through JVM properties.

First, set the following parameters in your JVM (commonly called -D parameters):

  -D "server-identity.application.environment=Development"
  -D "server-identity.application.instance.name=local"
  -D "server-identity.application.instance.enumeration=1"
  -D "server-identity.application.instance.description=Local Development Server #1"

Then, when calling the "initialize()" method, include an additional String parameter:

  PropertyListManager.initialize("MyApp","J");

Advanced Example 3.1 - Avoiding the Server-Identity XML File: NULL

Although it is highly recommended that a Server-Identity XML file be used to define your application's context, you can initialize a blank Habitat4J Server-Identity object containing NULL values. This means that Habitat4J will be used as a straight-forward property manager, and the context capabilities of Habitat4J are lost.

To do this, when calling the "initialize()" method include an additional String parameter:

  PropertyListManager.initialize("MyApp","N");

Advanced Example 3.2 - Habitat4J Features: Allowing Override of System & Security Properties

It may not be desirable to override System or Security properties that are already set. Therefore, by default, Habitat4J will not override them. To turn this behavior off, simply add one or both of these lines before the code used to load the Property-List XML files:

  PropertyListManager.setFeature(Habitat4JFeatures.PROPERTY_LIST_FEATURE_SYSTEM_PROPERTY_OVERRIDE,true);
  PropertyListManager.setFeature(Habitat4JFeatures.PROPERTY_LIST_FEATURE_SECURITY_PROPERTY_OVERRIDE,true);

Advanced Example 3.3 - Habitat4J Features: Allowing lax server role names

By default, Habitat4J only allows the following name attribute values for the role element in the Server-Identity XML file: appServer, dbServer, and webServer. To use other name attribute values, you can set this Habitat4J feature:

  PropertyListManager.setFeature(Habitat4JFeatures.SERVER_IDENTITY_FEATURE_LAX_ROLENAMES,true);

More examples coming! Please be patient.