image
 
image
GlobalProperties.java


/*::.
==================================================================================================================================
=================================================¦ Copyright © 2001 Allen Baker ¦=================================================
                                                 +------------------------------+
File:       GlobalProperties.java
Originator: Allen Baker (2001.11.03)
LayoutRev:  5
================================================================================================================================== */



/*.
==========================================================================================
Package
------------------------------------------------------------------------------------------ */
package cosmicabyss.com.lib;



/*.
==========================================================================================
Imports
------------------------------------------------------------------------------------------ */
import java.io.*;
import java.util.*;



/*::
======================================================================================================================== *//**
Instances of this class represent properties that are available to a program, primarily from the operating system
environment. These objects give access to the system's environment variables and provide services related to using the
environment variables. The object may also be used like any other properties object to store any additional key-value
pairs that the user chooses. Likely candidates for these additional key-value pairs include command line options.<P>

Java makes it difficult to get environment variables. In the past you could use System.getenv("environmentVariableName")
to retrieve environment variables. However, that now deprecated method will throw the following exception if you attempt
to call it:
   <BLOCKQUOTE>
      Exception in thread "main" java.lang.Error: getenv no longer supported, use properties and -D instead ...
   </BLOCKQUOTE>

Sun decided to deprecate the method because environment variables are a platform-specific feature, and some platforms,
MacOS for example, don't have the concept of an environment variable.<P>

This class solves the problem in a fairly portable way and without resorting to using the Java Native Interface, which
is an approach that most definitely violates portability.

<P>
   <DL>
      <DT>
         <B>
            Example usage:
         </B>
         <DD>
            <BLOCKQUOTE>
               <PRE id="unindent">
                  GlobalProperties  obj = new GlobalProperties();
                  //
                  ========================================================================================
                  List all the object's properties, get a single property, and search for various path -
                  file name combinations.
                  ---------------------------------------------------------------------------------------- //
                  obj.list(System.out);
                  cOut.println("obj.getProperty(\"JAVA_HOME\")             = "   + obj.getProperty     (new XString("JAVA_HOME")));
                  cOut.println("obj.getCanonicalPath(\"PATH\",\"clock.exe\") = " + obj.getCanonicalPath(new XString("PATH"),new XString("clock.exe")));
                  cOut.println("obj.getCanonicalPath(\"PATH\",\"expand\")    = " + obj.getCanonicalPath(new XString("PATH"),new XString("expand")));
                  cOut.println("obj.getCanonicalPath(null,\"clock.exe\")   = "   + obj.getCanonicalPath(null               ,new XString("clock.exe")));
                  cOut.println("obj.getCanonicalPath(\"PATH\",\"tuna.exe\")  = " + obj.getCanonicalPath(new XString("PATH"),new XString("tuna.exe")));
                  cOut.println("obj.getCanonicalPath(\"PATH\",\"\")          = " + obj.getCanonicalPath(new XString("PATH"),new XString("")));
                  cOut.println("obj.getCanonicalPath(\"PATH\",null)        = "   + obj.getCanonicalPath(new XString("PATH"),null));
                  cOut.println("obj.getCanonicalPath(\"CONFIGPATH\",null)  = "   + obj.getCanonicalPath(new XString("CONFIGPATH"),null));

                  obj.setProperty(new XString("FILETOFIND"),new XString("clock.exe"));
                  cOut.println("obj.getProperty(\"FILETOFIND\")            = "   + obj.getProperty(new XString("FILETOFIND")));

                  obj.setCanonicalPath(new XString("PATH"),new XString("FILETOFIND"));
                  cOut.println("obj.getProperty(\"FILETOFIND\")            = "   + obj.getProperty(new XString("FILETOFIND")));
               </PRE>
            </BLOCKQUOTE>
         </DD>
      </DT>
      <DT>
         <B>
            View Source:
         </B>
         <DD>
            <A href="GlobalProperties.java.html">
               GlobalProperties.java
            </A>
         </DD>
      </DT>
      <DT>
         <B>
            Author:
         </B>
         <DD>
            <A href="mailto:sourcecode.v01@cosmicabyss.com">
               Allen Baker
            </A>
         </DD>
      </DT>
   </DL>
*//*
======================================================================================================================== */
public class GlobalProperties extends Properties
   {



   /*:                                    :METHOD:000:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method reads the system environment variables and retains them in in the form of a Properties
   object.

   <P><B>Implementation: </B><A HREF="GlobalProperties.java.html#000">View source</A>

   *//*
   ---------------------------------------------------------------------------------------------------- */
   public GlobalProperties() throws Exception
      {
      Process  p  = null;
      Runtime  r  = Runtime.getRuntime();
      XString  os = new XString(System.getProperty("os.name").toLowerCase());
      /*.
      ==========================================================================================
      The command to get the environment variables is dependent on the os. Whether or not we
      need to be case sensitive regarding property names, file names, and directory names is
      also dependent on the os.
      ------------------------------------------------------------------------------------------ */
      if (os.indexOf("windows 9") > -1)    // tired old DOS Windows
         {
         p = r.exec("command.com /c set");
         iCaseSensitive = false;
         }
      else if (os.indexOf("windows") > -1) // Windows NT, 2000, XP and up
         {
         p = r.exec("cmd.exe /c set");
         iCaseSensitive = false;
         }
      else                                 // assume some variation of UNIX
         {
         p = r.exec("/bin/env");
         iCaseSensitive = true;
         }
      /*.
      ==========================================================================================
      Open the input stream that results from executing the command to list the environment
      variables.
      ------------------------------------------------------------------------------------------ */
      BufferedReader br = new BufferedReader
         (
         new InputStreamReader
            (
            p.getInputStream()
            )
         );
      /*.
      ==========================================================================================
      Load a Properties object with the environment variables.
      ------------------------------------------------------------------------------------------ */
      String line;
      while ( (line = br.readLine()) != null )
         {
         XString key;
         XString value;
         int    idx   = line.indexOf( '=' );
         if (idx != (-1))
            {
            key   = new XString(line.substring( 0, idx ));
            value = new XString(line.substring( idx+1 ));
            setProperty( key, value );
            }
         }
      }



   /*:                                    :METHOD:001:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method lists all the user and system environment variables

   <P><B>Implementation: </B><A HREF="GlobalProperties.java.html#001">View source</A>

   @param
      pOut is the PrintStream to which the list of environment variables is output.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public void list(PrintStream pOut)
      {
      super.list(pOut);
      System.getProperties().list(pOut);
      }



   /*:                                    :METHOD:002:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method lists all the user and system environment variables

   <P><B>Implementation: </B><A HREF="GlobalProperties.java.html#002">View source</A>

   @param
      pOut is the PrintWriter to which the list of environment variables is output.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public void list(PrintWriter pOut)
      {
      super.list(pOut);
      System.getProperties().list(pOut);
      }



   /*:                                    :METHOD:003:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method lists all the user and system environment variables on System.out.

   <P><B>Implementation: </B><A HREF="GlobalProperties.java.html#003">View source</A>

   *//*
   ---------------------------------------------------------------------------------------------------- */
   public void list()
      {
      super.list(System.out);
      System.getProperties().list(System.out);
      }



   /*:                                    :METHOD:004:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method adds a new variable or changes an existing variable to the GlobalProperties.

   <P><B>Implementation: </B><A HREF="GlobalProperties.java.html#004">View source</A>

   @return
      See JDK documentation.

   @param
      pKey is the key to be placed into this GlobalProperties.
   @param
      pValue is the value corresponding to pKey.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public <Type1,Type2> Object setProperty(Type1 pKey, Type2 pValue)
      {
      XString  key   = XString.toXString(pKey);
      XString  value = XString.toXString(pValue);
      /*.
      ==========================================================================================
      There has to be a key
      ------------------------------------------------------------------------------------------ */
      if (key == null)
         {
         return null;
         }
      if (key.equals(""))
         {
         return null;
         }
      /*.
      ==========================================================================================
      Set the key value
      ------------------------------------------------------------------------------------------ */
      key = canonicalString(key);
      return super.setProperty(key.string(),value.string());
      }



   /*:                                    :METHOD:005:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method adds all the properties in a Properties object to the GlobalProperties object. As is
   always the case, if a property being added clashes with one already there, the new one replaces the
   existing one.

   <P><B>Implementation: </B><A HREF="GlobalProperties.java.html#005">View source</A>

   @param
      pProperties is the Properties object whose properties are added to the GlobalProperties object.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public void setProperties(Properties pProperties)
      {
      Enumeration allKeys = pProperties.propertyNames();
      while (allKeys.hasMoreElements())
         {
         XString key = new XString((String)allKeys.nextElement());
         setProperty(key,new XString(pProperties.getProperty(key.string())));
         }
      }



   /*:                                    :METHOD:006:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method adds all the properties in a Properties file to the GlobalProperties object. As is
   always the case, if a property being added clashes with one already there, the new one replaces the
   existing one.

   <P><B>Implementation: </B><A HREF="GlobalProperties.java.html#006">View source</A>

   @param
      pFileName is the name of the Properties file whose properties are added to the GlobalProperties
      object.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public <Type1> void setProperties(Type1 pFileName) throws IOException
      {
      setProperties(new PropertyFile(XString.toXString(pFileName)));
      }



   /*:                                    :METHOD:007:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method searches for the environment variable (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 null if the property is not found.

   <P><B>Implementation: </B><A HREF="GlobalProperties.java.html#007">View source</A>

   @return
      The value in this property list with the specified key or null if the key is not found.

   @param
      pKey is the property to look up.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public <Type1> XString getProperty(Type1 pKey)
      {
      XString  key  = XString.toXString(pKey);
      /*.
      ==========================================================================================
      Protect subsequent method calls from null parameter
      ------------------------------------------------------------------------------------------ */
      if (pKey == null)
         {
         return null;
         }
      /*.
      ==========================================================================================
      First check the user properties
      ------------------------------------------------------------------------------------------ */
      XString value = new XString(super.getProperty(canonicalString(key).string()));
      if (value != null)
         {
         return value;
         }
      /*.
      ==========================================================================================
      It wasn't in the user properties so check the System properties
      ------------------------------------------------------------------------------------------ */
      return new XString(System.getProperty(key.string()));
      }



   /*:                                    :METHOD:008:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method searches for the environment variable (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 null if the property is not found.

   <P><B>Implementation: </B><A HREF="GlobalProperties.java.html#008">View source</A>

   @return
      The value in this property list with the specified key or the default value if the key is not
      found.

   @param
      pKey is the property to look up.
   @param
      pDefaultValue is the default value.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public <Type1,Type2> XString getProperty(Type1 pKey, Type2 pDefaultValue)
      {
      XString  key          = XString.toXString(pKey);
      XString  defaultValue = XString.toXString(pDefaultValue);
      XString  value;
      /*.
      ==========================================================================================
      Protect subsequent method calls from null parameter
      ------------------------------------------------------------------------------------------ */
      if (key == null)
         {
         return defaultValue;
         }
      /*.
      ==========================================================================================
      First check the user properties
      ------------------------------------------------------------------------------------------ */
      value = new XString(super.getProperty(canonicalString(key).string()));
      if (value != null)
         {
         return value;
         }
      /*.
      ==========================================================================================
      It wasn't in the user properties so check the System properties
      ------------------------------------------------------------------------------------------ */
      value = new XString(System.getProperty(key.string()));
      if (value != null)
         {
         return value;
         }
      /*.
      ==========================================================================================
      It wasn't there either so return the default value
      ------------------------------------------------------------------------------------------ */
      return defaultValue;
      }



   /*:                                    :METHOD:009:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method searches for the environment variable (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 null if the property is not found.

   <P><B>Implementation: </B><A HREF="GlobalProperties.java.html#009">View source</A>

   @return
      The value in this property list with the specified key value or null if the key is not found. The
      property value is returned as an ArrayList of tokens. The tokens are found by tokenizing the
      xString version of the property value using pDelimiter as the token delimiter.

   @param
      pKey is the property to look up.
   @param
      pDelimiter is the delimiter that separates tokens in the property value.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public <Type1,Type2> ArrayList<XString> getDelimitedProperty(Type1 pKey, Type2 pDelimiter)
      {
      XString  key       = XString.toXString(pKey);
      XString  delimiter = XString.toXString(pDelimiter);
      /*.
      ==========================================================================================
      Protect subsequent method calls from null parameter
      ------------------------------------------------------------------------------------------ */
      if (key == null)
         {
         return null;
         }
      /*.
      ==========================================================================================
      Get the property value as a XString and then parse it into tokens
      ------------------------------------------------------------------------------------------ */
      XString value = getProperty(key);
      if (value == null)
         {
         return null;
         }
      return value.tokenizedString(delimiter);
      }



   /*:                                    :METHOD:010:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method changes the value of a property containing a file name to a canonical form of the file
   name. It is given two propertties to work with: a property whose value is a path and a property
   whose value is the file name to be converted to canonical form. It searches the specified path for
   the specified file. If it finds the file, it changes the file name to its canonical name. If it
   doesn't find the file on the path, it changes the file name to a canonical name for a file with the
   specified file name in the current working directory. For example:
      <BLOCKQUOTE>
         <PRE id="unindent">
            assume the GlobalProperties object contains these two properties:
               CONFIGPATH=/wrong:/project/config
               CONFIGFILE=/hp/ces/config.properties

            assume that this file DOES NOT exist:
               /wrong/hp/ces/config.properties

            assume that this file DOES exist:
               /project/config/hp/ces/config.properties
         </PRE>
      </BLOCKQUOTE>

   Then setCanonicalPath("CONFIGPATH","CONFIGFILE") would search the path given by the property
   "CONFIGPATH" for the file given by the property "CONFIGFILE". It would find the file
   /hp/ces/config.properties in the directory /project/config and so it would change the value of
   "CONFIGFILE" to its canonical form. Then the GlobalProperties object would contain a new value for
   "CONFIGFILE":
      CONFIGFILE=/project/config/hp/ces/config.properties

   <P><B>Implementation: </B><A HREF="GlobalProperties.java.html#010">View source</A>

   @param
      pPathProperty is the environment variable name that contains a list of directories to check for
      the file. Usually this name would be "PATH".
   @param
      pFileNameProperty is the environment variable name that contains the file name to search the path
      for.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public <Type1,Type2> void setCanonicalPath
      (
      Type1  pPathProperty,
      Type2  pFileNameProperty
      )
      throws Exception
      {
      XString  pathProperty     = XString.toXString(pPathProperty);
      XString  fileNameProperty = XString.toXString(pFileNameProperty);
      setProperty
         (
         fileNameProperty,
         getCanonicalPath
            (
            pathProperty,
            getProperty(fileNameProperty)
            )
         );
      }



   /*:                                    :METHOD:011:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method searches the specified path for the specified file. If it finds the file, it returns its
   canonical name. If it doesn't find the file on the path, it returns a canonical name for a file with
   the specified file name in the current working directory.

   <P><B>Implementation: </B><A HREF="GlobalProperties.java.html#011">View source</A>

   @return
      The file's canonical name.

   @param
      pPathProperty is the environment variable name that contains a list of directories to check for
      the file. Usually this name would be "PATH".
   @param
      pFileName is the name of the file to search the path for.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public <Type1,Type2> XString getCanonicalPath(Type1 pPathProperty, Type2 pFileName) throws Exception
      {
      XString  pathProperty = XString.toXString(pPathProperty);
      XString  fileName     = XString.toXString(pFileName);
      File     theFile      = null;
      /*.
      ==========================================================================================
      Corner cases
      ------------------------------------------------------------------------------------------ */
      if (fileName == null)
         {
         fileName = new XString("");
         }
      if (pathProperty == null)
         {
         pathProperty = new XString("");
         }
      if (pathProperty.equals(""))
         {
         theFile = new File(fileName.string());
         return new XString(theFile.getCanonicalPath());
         }
      /*.
      ==========================================================================================
      If the path property isn't found or is empty then use the current working directory
      ------------------------------------------------------------------------------------------ */
      ArrayList<XString> dirs = getDelimitedProperty
         (
         pathProperty,new XString(System.getProperty("path.separator"))
         );
      if ((dirs == null) || (dirs.size() == 0))
         {
         theFile = new File(fileName.string());
         return new XString(theFile.getCanonicalPath());
         }
      /*.
      ==========================================================================================
      If it is found, break it up into its constituent directories and look in each directoy in
      succession until the file is found.
      ------------------------------------------------------------------------------------------ */
      for (int i=0; i<dirs.size(); i++)
         {
         theFile = new File(dirs.get(i).string(), fileName.string());
         if (theFile.exists())
            {
            return new XString(theFile.getCanonicalPath());
            }
         }
      /*.
      ==========================================================================================
      If the file wasn't found anywhere on the path, use the current working directory.
      ------------------------------------------------------------------------------------------ */
      theFile = new File(fileName.string());
      return new XString(theFile.getCanonicalPath());
      }



   /*:                                    :METHOD:012:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method sets the ConsoleStream for this object.

   <P><B>Implementation: </B><A HREF="GlobalProperties.java.html#012">View source</A>

   @return
      A reference to this object

   @param
      pConsole is a ConsoleStream through which this objects sends its output.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public GlobalProperties setOut(ConsoleStream pConsole)
      {
      cOut = pConsole;
      return this;
      }



   /*:                                    :METHOD:013:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This boilerplate method is used for testing an instantiated object of this class and may include any
   code the developer chooses.

   <P><B>Implementation: </B><A HREF="GlobalProperties.java.html#013">View source</A>

   *//*
   ---------------------------------------------------------------------------------------------------- */
   public GlobalProperties test() throws Exception
      {
      cOut.titledPrintf
         (
         "\"HELLO WORLD!\"",
         "%s  %s  %s",
         "I'm an object of the", CLASS_NAME, "class, and I approved this message."
         );
      return this;
      }



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Protected  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Private  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   /*.
   ==========================================================================================
   Class Constants
      CLASS_NAME:
         The name of this class
      DFLT_LINE_LEN:
         The default line length for word wrapping
   ------------------------------------------------------------------------------------------ */
   private static final XString  CLASS_NAME    = new XString(GlobalProperties.class.getName());
   private static final int      DFLT_LINE_LEN = ConsoleMessage.defaultLineLength();
   /*.
   ==========================================================================================
   Class variables
      cOut : console output.
   ------------------------------------------------------------------------------------------ */
   private static ConsoleStream  cOut = ConsoleStream.getSingleton();
   /*.
   ==========================================================================================
   Instance variables
      iCaseSensitive:
         Do we need to be case sensitive regarding property names, file names, and directory
         names? (The answer is going to depend on the os.)
   ------------------------------------------------------------------------------------------ */
   private boolean        iCaseSensitive  = true;



   /*:                                    :METHOD:014:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method returns its input XString in standard form. If the system that this class is running on
   is case sensitive regarding property names, file names, and directory names, then the canonical
   xString is the same as the input XString. If the system is not case sensitive, then the canonical
   xString is a representation of the input XString that allows case insensitive comparisons to be made
   to that XString.

   <P><B>Implementation: </B><A HREF="GlobalProperties.java.html#014">View source</A>

   @param
      pStr is the XString that is converted into standard form.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   private XString canonicalString(XString pStr)
      {
      if (pStr == null)
         {
         return null;
         }
      return iCaseSensitive? pStr : pStr.toLowerCase();
      }



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Inner Classes  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Public Static Methods  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   /*:                                    :METHOD:015:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method allows this class file to be unit tested as a standalone application. It's the method
   that's called when the class is invoked from the command line by using the java application launcher
   - "java". Main() is not a required method, but the practice of putting one in each class and
   wrapping class test code within it allows easy unit testing of the class; and main does not need to
   be removed when testing is complete.

   <P>
      <DL>
         <DT>
            <B>
               Command line usage:
            </B>
            <DD>
               Java cosmicabyss.com.lib.GlobalProperties
            </DD>
         </DT>
      </DL>

   <P><B>Implementation: </B><A HREF="GlobalProperties.java.html#015">View source</A>

   @param
      pArgs contains the command line arguments with which this class was invoked as an application.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public static void main(String[] pArgs) throws Exception
      {
      /*.
      ==========================================================================================
      Greetings !
      ------------------------------------------------------------------------------------------ */
      cOut.banner(CLASS_NAME);
      /*.
      ==========================================================================================
      Create an object and send its output to the ConsoleStream
      ------------------------------------------------------------------------------------------ */
      GlobalProperties  obj = new GlobalProperties();
      /*.
      ==========================================================================================
      Test code
      ------------------------------------------------------------------------------------------ */
      obj.test();
      /*.
      ==========================================================================================
      List all the object's properties, get a single property, and search for various path -
      file name combinations.
      ------------------------------------------------------------------------------------------ */
      obj.list(System.out);
      cOut.println("obj.getProperty(\"JAVA_HOME\")             = "   + obj.getProperty     (new XString("JAVA_HOME")));
      cOut.println("obj.getCanonicalPath(\"PATH\",\"clock.exe\") = " + obj.getCanonicalPath(new XString("PATH"),new XString("clock.exe")));
      cOut.println("obj.getCanonicalPath(\"PATH\",\"expand\")    = " + obj.getCanonicalPath(new XString("PATH"),new XString("expand")));
      cOut.println("obj.getCanonicalPath(null,\"clock.exe\")   = "   + obj.getCanonicalPath(null               ,new XString("clock.exe")));
      cOut.println("obj.getCanonicalPath(\"PATH\",\"tuna.exe\")  = " + obj.getCanonicalPath(new XString("PATH"),new XString("tuna.exe")));
      cOut.println("obj.getCanonicalPath(\"PATH\",\"\")          = " + obj.getCanonicalPath(new XString("PATH"),new XString("")));
      cOut.println("obj.getCanonicalPath(\"PATH\",null)        = "   + obj.getCanonicalPath(new XString("PATH"),null));
//      cOut.println("obj.getCanonicalPath(\"CONFIGPATH\",null)  = "   + obj.getCanonicalPath(new XString("CONFIGPATH"),null));

      if (pArgs.length < 1)
         {
         obj.setProperty(new XString("FILETOFIND"),new XString("clock.exe"));
         }
      else
         {
         obj.setProperty(new XString("FILETOFIND"),new XString(pArgs[0]));
         }
      cOut.println("obj.getProperty(\"FILETOFIND\")            = "   + obj.getProperty(new XString("FILETOFIND")));
      obj.setCanonicalPath(new XString("PATH"),new XString("FILETOFIND"));
      cOut.println("obj.getProperty(\"FILETOFIND\")            = "   + obj.getProperty(new XString("FILETOFIND")));
      }



   }  // class GlobalProperties



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Notes  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */