com.cleancode.data
Class ParamMap

java.lang.Object
  extended by java.util.AbstractMap<K,V>
      extended by java.util.TreeMap<String,String>
          extended by com.cleancode.data.ParamMap
All Implemented Interfaces:
Serializable, Cloneable, Map<String,String>, NavigableMap<String,String>, SortedMap<String,String>

public class ParamMap
extends TreeMap<String,String>

Manages a collection of parameters and their associated tool tips.

  // create a new object with a constant argument list.
  paramMap = new ParamMap({"arg1","tooltip1"}, {"arg2","tooltip2"},...});

  // add parameters for classes used by this class
  // so displaying a usage summary will show all parameters
  paramMap.putAll(Diagnostic.paramMap);

  // pass to InputOptions to validate arguments automatically...
  settings = new InputOptions(args, null, null, paramMap);

  // ... or check manually (for specific or pattern-matched argument) 
  if (!paramMap.containsKey(argName)) ...

  // print list of params and tool tips with specified indent
  if (badArgs) System.err.println(paramMap.toString("  "));

  // print list of params and tool tips with no indent
  System.err.println(paramMap);
 
This class extends a standard hash with some handy features for managing program configuration parameters. Typically, you will have a known, constant set of parameters that your program will use. Create a simple constant list of these parameters, wherein each one is associated with a "tool tip"--a short text fragment describing the purpose of the parameter. Most command-line oriented programs have a standard "usage" summary, listing all of the parameters (or options) and the purpose of each. Using a ParamMap you can do this with trivial code. Here's a sample list of parameters for a program, followed by a constructor for our object:
  private static final String[][] paramList = {
    { "sourcePath","root of source XML tree" },
    { "targetPath","root of target XML tree" },
    { "enable","do processing if true; just report if false" },
    { "help","show this list" }
  };
  private static ParamMap paramMap = new ParamMap(paramList);
 
If you then have a routine that displays a usage summary, all you have to do is print the ParamMap, as in:
  private static void usage() {
    System.err.println("usage: program-x);
    System.err.println();
    System.err.println(paramMap);
  }
 
The output of the above method would simply be:
  usage: program-x

  sourcePath -- root of source XML tree
  targetPath -- root of target XML tree
  enable     -- do processing if true; just report if false
  help       -- show this list
 
But let's say your program uses another module, such as CleanCode's Diagnostic module, and you allow the user to specify command-line input parameters that may also be used by this included module. But then the above usage() method is not really complete, as it does not show the parameters used by the other module(s). As long the included modules also use a ParamMap, you only need one line of code to merge the two lists:
   paramMap.putAll(Diagnostic.paramMap);
 
Then when you print the paramMap, it will list not only your parameters, but those of the Diagnostic module (in this example). But this merged list is not just for a usage() method. It also comes into play when you want to validate the argument list passed to your program. When you call the containsKey() method to see whether an argument passed in is one that you are expecting, the method will now check against your local list plus the lists from the included modules you have merged via the putAll() method. (While you are certainly free to do manual validation of the argument list, the CleanCode InputOptions module will do it for you by just passing in your top-level paramMap.)

Finally, a ParamMap is not limited to an enumerated set of parameters. You may use regular expressions in your parameters to match a class of names. Like many things, this has advantages and disadvantages. You gain flexibility in what you can accept, but then you lose the ability to do strict validation. (Some regular expressions would match an infinite number of strings, and clearly you wouldn't be expecting all of them.) This flexibility is very handy in the case, for instance, where the allowable parameters depends upon things that happen at runtime. The Diagnostic module, for example, allows each loaded class to have its own diagnostic level parameter, where the name is classname_DIAG. But when you, as a developer, use the Diagnostic module, you don't want to concern yourself with all the other CleanCode modules loaded along with the Diagnostic module. Further, you may even use dynamic class loading, where you couldn't know which modules in advance even if you wanted to. So the Diagnostic module includes this in its ParamMap:
  { ".*_DIAG", "diagnostic level for any class" },
 
Then your argument list may contain DIAGNOSTIC_DIAG, FOOBAR_DIAG, or any other diagnostic level, and they will all pass validation.

Since:
CleanCode 0.9
Version:
$Revision: 9 $
Author:
Michael Sorens
See Also:
Serialized Form

Nested Class Summary
 
Nested classes/interfaces inherited from class java.util.AbstractMap
AbstractMap.SimpleEntry<K,V>, AbstractMap.SimpleImmutableEntry<K,V>
 
Field Summary
static String SEPARATOR
          Separates each key from its tool tip when a ParamMap is printed as a string.
static String VERSION
          Current version of this class.
 
Constructor Summary
ParamMap(String[][] paramList)
          Creates a ParamMap object initialized with the specified paramList.
 
Method Summary
 boolean containsKey(Object key)
          Determines if the specified key matches an element of the ParamMap either as a specific string or as a regular expression.
 void putAll(ParamMap newMap)
          Merges the new map with the current map.
 String toString()
          Converts the object to a string representation with no indent.
 String toString(String indent)
          Converts the object to a string representation with the specified indent on each line.
 
Methods inherited from class java.util.TreeMap
ceilingEntry, ceilingKey, clear, clone, comparator, containsValue, descendingKeySet, descendingMap, entrySet, firstEntry, firstKey, floorEntry, floorKey, get, headMap, headMap, higherEntry, higherKey, keySet, lastEntry, lastKey, lowerEntry, lowerKey, navigableKeySet, pollFirstEntry, pollLastEntry, put, putAll, remove, size, subMap, subMap, tailMap, tailMap, values
 
Methods inherited from class java.util.AbstractMap
equals, hashCode, isEmpty
 
Methods inherited from class java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface java.util.Map
equals, hashCode, isEmpty
 

Field Detail

VERSION

public static final String VERSION
Current version of this class.


SEPARATOR

public static final String SEPARATOR
Separates each key from its tool tip when a ParamMap is printed as a string.

See Also:
Constant Field Values
Constructor Detail

ParamMap

public ParamMap(String[][] paramList)
Creates a ParamMap object initialized with the specified paramList.

Parameters:
paramList - list of 2-element sublists, where each sublist contains a parameter name and a description of its use. The parameter name may either be a simple string or a regular-expression.
Method Detail

containsKey

public boolean containsKey(Object key)
Determines if the specified key matches an element of the ParamMap either as a specific string or as a regular expression.

Specified by:
containsKey in interface Map<String,String>
Overrides:
containsKey in class TreeMap<String,String>
Parameters:
key - parameter name to check for match (defined as an Object since this method overrides the base class, but should be castable to String)
Returns:
boolean indicating whether the specified key is in the ParamMap

putAll

public void putAll(ParamMap newMap)
Merges the new map with the current map. Elements in the new map which are already in the current map are not changed. Any such conflicts are reported in an UnsupportedOperationException.

Parameters:
newMap - map to merge with the current map.

toString

public String toString()
Converts the object to a string representation with no indent.

Overrides:
toString in class AbstractMap<String,String>
Returns:
string representation of the map

toString

public String toString(String indent)
Converts the object to a string representation with the specified indent on each line. One parameter name and description are listed on each line in the format parameter -- description. The spacing to the left of the "--" separator is determined by calculating the length of the longest parameter name.

Parameters:
indent - String used for indentation
Returns:
string representation of the map


CleanCode Java Libraries Copyright © 2001-2012 Michael Sorens - Revised 2012.12.10 Get CleanCode at SourceForge.net. Fast, secure and Free Open Source software downloads