An object of this class represents a variable-size path for identifying
the location of a datum within an HL7 message, which we can use for
maintaining parser state and for generating a suitable string key (in the
ZYX[a]-b[c]-d-e style) for a piece of data in the message (see toString()).
The elements are:
segmentID / segmentRepIdx / fieldIdx / fieldRepIdx / compIdx / subcompIdx
("rep" means "repetition")
segmentID is a String, the rest are Integers.
It is variable-size path-style in that if it has a size of 1, the one element
will be the segmentID; if it has a size of two, element 0 will be the segmentID
and element 1 will be the segmentRepIdx, etc. This class can't represent a
fieldIdx without having segmentID / segmentRepIdx, etc. etc.
possible sizes: 0 to 6 inclusive
As toString() simply converts this's integer values to strings (1 => "1"), and
since for some reason the ZYX[a]-b[c]-d-e style counts b, d, e starting from 1
and a, c from 0 -- it is intended that one store the numeric values in this
class starting from 1 for fieldIdx (element 2), compIdx (4) and subcompIdx
(5), and from 0 for segmentRepIdx (1) and fieldRepIdx (3). default values
provided by setSize() and by toString() do this.
set() sets an element of the path.
idx must be in [0, size()). else => IndexOutOfBoundsException.
(new_value == null) => NullPointerException
new_value must be either a String or an Integer depending on what part
of the path you're setting:
(idx == 0) => String
(idx >= 1) => Integer
If new_value can't be cast to the appropriate type, a ClassCastException
is thrown before new_value is stored.
Of course, on success, this will discard it's reference that used to be at
get() returns an element, which will be either a String or an Integer.
((idx == 0) => String
(idx >= 1) => Integer
((idx < 0) || (idx >= size())) => IndexOutOfBoundsException
We will attempt to cast the gotten object to the appropriate type before
returning it as an Object. That way, if there's an object of the wrong type
in the wrong place in here (that got past set() somehow), then a
ClassCastException will be thrown even if the caller of this function
doesn't try to cast it. (consider System.out.println("val: " + path.get(n))
nothing would barf it this get() wasn't vigilant.)
toString() outputs the path (from segmentID onward) in the ZYX[a]-b[c]-d-e
style (TODO: give it a name), suitable for a key in a map of
message datum paths to values.
Integer values are converted to strings directly (1 => "1") so when you
constructed this you should have started counting from 1 for everything but
the "repeat" fields, if you truly want the ZYX[a]-b[c]-d-e style.
If toString() is called when this has a size in [1, 6) (=> missing numeric
elments), then we act as though the elements in [size(), 6) are 0 or 1 as
appropriate for each element. We don't provide a default for the element 0
(the String element): will throw an IndexOutOfBoundsException if (size() ==
eg. a (new DatumPath()).add(new String("ZYX")).add(2).add(6).toString()
would yield "ZYX-6-1-1"
add() grows this by 1, inserting newValue at the end.
newValue must be a String or an Integer depending on the index where it will
be inserted, as noted at DatumPath.set().
(newValue == null) => NullPointerException
Like add(String). convenient wrapper for add(Object), when the object
to be added must be an Integer anyway (size() > 0 on entry).
For the user, it turns
path.add(new Integer(i)).add(new Integer(j)).add(new Integer(k))
path.add(i).add(j).add(k), that's all.
size() == 0 on entry throws a ClassCastException (which it is, kindof),
otherwise calls add(new Integer(new_value)).
setSize(): resize. If this will grow the object, then we put default
values into the new elements: "" into the String element, Integer(1) into the
elements 2, 4, and 5, and Integer(0) into elements 1 and 3.