org.web3d.vrtp.dabp
Class OrderedMap

java.lang.Object
  |
  +--java.util.AbstractMap
        |
        +--org.web3d.vrtp.dabp.OrderedMap
All Implemented Interfaces:
java.lang.Cloneable, java.util.Map, Primitive

public class OrderedMap
extends java.util.AbstractMap
implements Primitive, java.lang.Cloneable

Really simple class that handles attribute-value pairs, in the order they were addded. For example,

Attribute Value --------- ----- "Fred" PersonObjectInstance "Joe" managerObjectInstace "Suzy" modelObjectInstance "Employees" OrderedMapInstance "Joe Bloggs" employeeObjectInstance "Joe Sixpack" employeeObjectInstance

The OrderedMap keeps instances in the order in which they were added; put("Fred", personObjectInstance) and put("Joe", personObjectIntance) means that fred will always be listed before joe. You can also nest OrderedMaps; in the above example, the ordered map includes in turn another ordered map, referenced by the attribute "employees".

One of the major design issues here was whether to use the JDK 1.2 collection classes, the pre-1.2 collections, or a third party collections framework.

The major third-party collections framework is from objectspace (http://www.objectspace.com/developers/jgl/). It is closely modeled on the C++ STL.

The pre-1.2 collections are basically Hashtable and Vector.

JDK 1.2 introduced a new collections framework that imposes a bit more order and capability.

A good review of the JDK1.2 vs. JGL issue is at http://www.javaworld.com/javaworld/jw-01-1999/jw-01-jglvscoll.html Basically, JGL is more capable, but with a steeper learning curve, and, while free, is not a standard part of the JDK distribution. The resemblence to the STL library would be good for porting to C++.

The clinching argument for me was that other elements of the JDK core classes will probably be congealing around the 1.2 collections framework. Using JGL would probably mean doing a lot of conversions between the JGL classes and java collection classes to pass things into other core JDK release objects (say, GUI elements.)

OrderedMap is an implementation of the Map interface, which represents object-pair values, not unlike a hash table. The difference is that OrderedMap preserves the order; if something is added, it can stay in a specific place in the collection. This is required for handling fields, in which order is very, very important.

This subclasses AbstractMap, a convienice class provided by Sun to take care of most of the details of implementing the Map interface.

Note that this uses internally the _new_ Vector class. You should use the List interface to interact with the new Vector class, so that you don't get tied to the old way of doing things.

This makes use of a couple inner classes and one anonymous class, which are moderately obscure portions of the Java language. Basically, inner classes are "helper classes" that are closely coupled to a particular class. They could, in theory, be stand-alone classes, but since they make sense only when used with another class, they are syntactically "enclosed" by that class. They're refered to via OuterClass.InnerClass notation. I'm of two minds about this; while they're probably a good idea, they're also difficult for newbies to grasp. The clincher is that they're also basically required by the Map interface in the collections framework, eg Map.Entry.

Anonymous classes are like inner classes, but have no name. They just conform to an interface.

For a discussion of inner classes, see http://www.performancecomputing.com/columns/java/9806.shtml

This class includes references to XML, which is a highly questionable decision. OrderedMap is general purpose enough to get along without the XML references. But it makes it easier to create nested attribute-value lists if this is in a constructor.

this is almost, but not quite, a generally useful and reusable class, which annoys me to no end.

Author: Don McGregor


Inner Class Summary
(package private)  class OrderedMap.Entry
          Another inner class, this one for Map.Entry.
 
Inner classes inherited from class java.util.Map
java.util.Map.Entry
 
Field Summary
protected  java.util.Vector entries
           
protected  java.lang.String name
           
 
Constructor Summary
OrderedMap(org.w3c.dom.Element directoryEntry)
          A constructor that takes a DOM node in a specified format and creates key-value pairs from the result.
OrderedMap(java.lang.String pName)
          Constructor; takes a name for this directory, default, empty stuff for the rest.
 
Method Summary
 java.lang.Object clone()
          clone operation; given an ordered map, returns another ordered map that shares no internal data structures.
 int compareTo(java.lang.Object obj)
          Implementation of the Comparable interface.
 java.util.Set entrySet()
          Returns a set view of the mappings contained in this map.
 java.lang.Object get(int pIdx)
          Get an object at a specific index.
 java.lang.Object get(java.lang.Object pKey)
          Get a value back out for the key passed in.
 int getLength()
          like the above, but a different name, because I can never remember.
 java.lang.String getName()
          Returns the name of this ordered map.
 int getSize()
          Number of bytes this takes up when serialized.
 int hashcode()
          Generate a hashcode for an ordered map.
 void initializeWithBinary(byte[] pData, int pOffset)
          this is unexercised right now.
 void initializeWithString(java.lang.String pString)
          This is not implemented right now.
static void main(java.lang.String[] args)
          Used for debugging and testing purposes
 java.lang.Object put(java.lang.Object pObject, int pIdx)
          Puts an element at a specific place in the map.
 java.lang.Object put(java.lang.Object pKey, java.lang.Object pValue)
          Put a string and a value into the database.
 java.lang.Object put(OrderedMap.Entry pEntry)
          Add a new Map.Entry object (key, value) to the OrderedMap.
 void serialize(java.io.DataOutputStream pOutputStream)
          Serialize data, using our own internal scheme, completely separate from that of the JDK serialization/externalizable scheme.
 void setName(java.lang.String pName)
           
 int size()
          returns the size of the OrderedMap, which is just the number of entries.
 java.lang.String toString()
          toString is a method used lots of places in the JDK; it's what is called by System.out.println() on objects that appear in println statements.
protected  boolean valEquals(java.lang.Object o1, java.lang.Object o2)
          Test two values for equality.
 
Methods inherited from class java.util.AbstractMap
clear, containsKey, containsValue, equals, hashCode, isEmpty, keySet, putAll, remove, values
 
Methods inherited from class java.lang.Object
, finalize, getClass, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface org.web3d.vrtp.datatypes.Primitive
equals, hashCode
 

Field Detail

name

protected java.lang.String name

entries

protected java.util.Vector entries
Constructor Detail

OrderedMap

public OrderedMap(java.lang.String pName)
Constructor; takes a name for this directory, default, empty stuff for the rest.

OrderedMap

public OrderedMap(org.w3c.dom.Element directoryEntry)
A constructor that takes a DOM node in a specified format and creates key-value pairs from the result. This MUST be one of our elements, which has children in the form 23. This is an arguable choice for a constructor, since it implies that the XML stuff will be around all the time. But OrderedMap is a general purpose class that can be used in contexts other than XML, so tying it to XML is a Bad Thing. On the other hand, using this in a constructor makes things much easier. A typical element would look like this: UnsignedByte 0 It's a directory; the first entry in the directory is named "ProocolVersion", and its value is in turn another directory, this time named "FieldInfo". It has entries for FieldType and DefaultValue (values "UnsignedByte" and "0", respectively.)
Method Detail

entrySet

public java.util.Set entrySet()
Returns a set view of the mappings contained in this map. Each element in this set is a Map.Entry. The set is backed by the map, so changes to the map are reflected in the set, and vice-versa. (If the map is modified while an iteration over the set is in progress, the results of the iteration are undefined.) The set supports element removal, which removes the corresponding entry from the map, via the Iterator.remove, Set.remove, removeAll, retainAll and clear operations. It does not support the add or addAll operations. This method does some medium-deep magic, and uses some obscure Java features, namely anonymous classes. The bit after AbstractSet() is an anonymous class, a class declared "on the fly" and without a name. It conforms to the Set interface, and is an instance of AbstractSet with a few methods overridden.
Overrides:
entrySet in class java.util.AbstractMap

valEquals

protected boolean valEquals(java.lang.Object o1,
                            java.lang.Object o2)
Test two values for equality. Differs from o1.equals(o2) only in that it copes with with null o1 properly.

initializeWithBinary

public void initializeWithBinary(byte[] pData,
                                 int pOffset)
this is unexercised right now. These two methods must be implemented in order to implement the Primitive interface.
Specified by:
initializeWithBinary in interface Primitive

initializeWithString

public void initializeWithString(java.lang.String pString)
This is not implemented right now. It's a placeholder for the Primitive interface, which I want to use in a couple places.
Specified by:
initializeWithString in interface Primitive

clone

public java.lang.Object clone()
clone operation; given an ordered map, returns another ordered map that shares no internal data structures. This may recurse if a value is itself an ordered map.
Specified by:
clone in interface Primitive
Overrides:
clone in class java.lang.Object

put

public java.lang.Object put(OrderedMap.Entry pEntry)
Add a new Map.Entry object (key, value) to the OrderedMap.

put

public java.lang.Object put(java.lang.Object pKey,
                            java.lang.Object pValue)
Put a string and a value into the database. This makes the Map a mutable map. If this replaces an existing key, return the object replaced; otherwise, return null.
Overrides:
put in class java.util.AbstractMap

getName

public java.lang.String getName()
Returns the name of this ordered map.

setName

public void setName(java.lang.String pName)

get

public java.lang.Object get(int pIdx)
Get an object at a specific index. Returns null if the object is beyond the index; you should handle this error in your own code.

put

public java.lang.Object put(java.lang.Object pObject,
                            int pIdx)
Puts an element at a specific place in the map. Returns the object replaced if the object already exists; null otherwise. May be mull if the existing object was already null. Fails silently if the index is out of bounds, which sucks. Need to rethink this. Throwing an exception would be annoying, becuase you'd have to catch it all the time.

get

public java.lang.Object get(java.lang.Object pKey)
Get a value back out for the key passed in. If you want a field inside an orderedMap that is nested within this, use the format "name1.name2". eg, "Position.x", "Position.y" to get the x and y of a field named Position that is itself an ordered map. Note that case is significant (grr, should be fixed), so that "postion.x" and "Position.x" are not the same thing.
Overrides:
get in class java.util.AbstractMap

toString

public java.lang.String toString()
toString is a method used lots of places in the JDK; it's what is called by System.out.println() on objects that appear in println statements. This converts an object to a string representation.
Specified by:
toString in interface Primitive
Overrides:
toString in class java.util.AbstractMap

size

public int size()
returns the size of the OrderedMap, which is just the number of entries.
Overrides:
size in class java.util.AbstractMap

getLength

public int getLength()
like the above, but a different name, because I can never remember. returns number of elements in the OrderedMap.

getSize

public int getSize()
Number of bytes this takes up when serialized. this is computing using our own internal scheme for serialization; other schemes, such as the java or corba serialization, might be different. This recurses down to the primitive types it contains, adding up the total size taken along the way.
Specified by:
getSize in interface Primitive

serialize

public void serialize(java.io.DataOutputStream pOutputStream)
Serialize data, using our own internal scheme, completely separate from that of the JDK serialization/externalizable scheme.
Specified by:
serialize in interface Primitive

hashcode

public int hashcode()
Generate a hashcode for an ordered map. This is just the XOR of all the entries for this ordered map. As always, it may recurse on nested OrderedMaps.

compareTo

public int compareTo(java.lang.Object obj)
Implementation of the Comparable interface. This is used by standard Java utilties classes to do things like sort arrays and the like. So as long as you implement this, you get sorting for "free". This is actually a very tricky operation, since the layout of the ordered trees may be completley different. For now I just punt, and say all OrderedMaps have the same lexigraphic value. Which means sort operations will basicaly punt to, usually resulting in the same order as the input.
Specified by:
compareTo in interface Primitive

main

public static void main(java.lang.String[] args)
Used for debugging and testing purposes