HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML
 

"Enabling Constant Substitution in Property Values"
Vol. 6, Issue 12, p. 52

	


Listing 1: Sample Properties

# Sample.properties
#
# These properties illustrate the use of constants
# within property values, accessed using the
# XProperties class.


# Use several levels of recursive substitution to
# define paths for different resource types
ROOT_DRIVE=c:
BASE_DIR={ROOT_DRIVE}/base
HTML_DIR={BASE_DIR}/html
XML_DIR={BASE_DIR}/xml
IMAGE_DIR={BASE_DIR}/image


# Define full pathnames for resource files
MyHtmlFile={HTML_DIR}/MyFile.html
MyXmlFile={XML_DIR}/MyFile.xml
NewImage={IMAGE_DIR}/new.gif
SaveImage={IMAGE_DIR}/save.gif
PrintImage={IMAGE_DIR}/print.gif



# Assemble a property value from several constants
PROTOCOL=https
SERVER=server.acme.com
PORT=80
RESOURCE=index.html
HomePageURL={PROTOCOL}//{SERVER}:{PORT}/{RESOURCE}



# Define a constant for each possible value
UNIT_TEST_URL = http://localhost:8080/abc
SYSTEM_TEST_URL = http://testserver.acme.com/abc
PRODUCTION_URL= http://prodserver.acme.com/abc


# Select from the possible values
MyURL = {UNIT_TEST_URL}



Listing 2: Sample Java Code to Use XProperties

// import java.io.*;
// Create an XProperties and load the property file
Properties prop = new XProperties();
InputStream in = new FileInputStream("Sample.properties");
prop.load(in);


// List the keys for the property values of interest
String[] keys = {
        "MyHtmlFile", "MyXmlFile",
        "NewImage", "SaveImage", "PrintImage",
        "HomePageURL", "MyURL" };


// Iterate through the keys; display key and value
for (int i=0; i < keys.length; i++) {
        String value = prop.getProperty(keys[i]);
        System.out.println(keys[i]+" = "+value);
}


Listing 3: Resulting Output from Code in Listing 2

MyHtmlFile = c:/base/html/MyFile.html
MyXmlFile = c:/base/xml/MyFile.xml
NewImage = c:/base/image/new.gif
SaveImage = c:/base/image/save.gif
PrintImage = c:/base/image/print.gif
HomePageURL = https//server.acme.com:80/index.html
MyURL = http://localhost:8080/abc


Listing 4: Source Code for XProperties Class

import java.util.Properties;
/**
 * A subclass of Properties that allows recursive
 * references for property values. For example,
 *
 * <pre><code>
 * A=12345678
 * B={A}90
 * C={B} plus more
 * </code></pre>
 *
 * will result in <code>getProperty("C")</code>
 * returning the value "1234567890 plus more".
 *
 * @author: Chris Mair
 */
public class XProperties extends Properties {


   // The prefix and suffix for constant names
   // within property values
   private static final String START_CONST = "{";
   private static final String END_CONST = "}";


   // The maximum depth for recursive substitution
   // of constants within property values
   // (e.g., A={B} .. B={C} .. C={D} .. etc.)
   private static final int MAX_SUBST_DEPTH = 5;


/**
 * Creates an empty property list with no default
 * values.
 */
public XProperties() {
   super();
}


/**
 * Creates an empty property list with the
 * specified defaults.
 * @param defaults java.util.Properties
 */
public XProperties(Properties defaults) {
   super(defaults);
}


/**
 * Searches for the property with the specified
 * key in this property list. If the key is not
 * found in this property list, the default
 * property list, and its defaults, recursively,
 * are then checked. The method returns
 * <code>null</code> if the property is not found.
 *
 * @param   key   the property key.
 * @return  the value in this property list with
 *    the specified key value.
*/
public String getProperty(String key) {


   // Return the property value starting at level 0
   return getProperty(key, 0);
}


/**
 * Searches for the property with the specified
 * key in this property list. If the key is not
 * found in this property list, the default
 * property list, and its defaults, recursively,
 * are then checked. The method returns
 * <code>null</code> if the property is not found.
 *
 * <p>The level parameter specifies the current
 * level of recursive constant substitution. If
 * the requested property value includes a
 * constant, its value is substituted in place
 * through a recursive call to this method,
 * incrementing the level. Once level exceeds
 * MAX_SUBST_DEPTH, no further constant
 * substitutions are performed within the
 * current requested value.
 *
 * @param   key   the property key.
 * @param level  the level of recursion so far
 * @return  the value in this property list with
 * the specified key value.
 */
private String getProperty(String key, int level) {


   String value = super.getProperty(key);
   if (value != null) {


      // Get the index of the first constant, if any
      int beginIndex = 0;
      int startName = value.indexOf(START_CONST, beginIndex);


      while (startName != -1) {
         if (level+1 > MAX_SUBST_DEPTH) {
            // Exceeded MAX_SUBST_DEPTH
            // Return the value as is
            return value;
         }


         int endName = value.indexOf(END_CONST, startName);
         if (endName == -1) {
            // Terminating symbol not found
            // Return the value as is
            return value;
         }


         String constName = value.substring(startName+1, endName);
         String constValue = getProperty(constName, level+1);


         if (constValue == null) {
            // Property name not found
            // Return the value as is
            return value;
         }


         // Insert the constant value into the
         // original property value
         String newValue = (startName>0)
            ? value.substring(0, startName) : "";
         newValue += constValue;


         // Start checking for constants at this index
         beginIndex = newValue.length();


         // Append the remainder of the value
         newValue += value.substring(endName+1);


         value = newValue;


         // Look for the next constant
         startName = value.indexOf(START_CONST, beginIndex);
      }
   }


   // Return the value as is
   return value;
}
}

  
 
 

All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: [email protected]

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.