RecursiveRoomLoader.html
25sep10 CmdrZin

ref1: Core Java, Vol 1, Java SE 6
ref2: MudMain.java
ref3: Room.java
ref4: MubObject.java

Understanding the Recursive Room Loader

    The initial map, items, and monsters are all loaded once by MudMain::initialize(). This function is called by the RDS Kernel (I believe) to launch the application. It is passed the Properties filename that was in the *.boot file equated to
    SGS_PROPERTIES=${SGS_HOME}/tutorial/conf/MudMain.properties
in the case of this game. The Property map file is a string based key::value pair file[1]. These are normally used for storing user preferences for an application. But they can be used for just about any thing needed a key::pair structure. The New Room file talks about the structure being used by this game.
    After some setup, the initialize() method calls loadRoom() and sends it the Properties filename and the name (key) for the first room. This is a lookup process, so the file does not have to be in any particular order. I have grouped the key::values that are associated together though.
    loadRoom() is an overloaded method. The initial one starts and ends the recursive process. It builds up a HashMap to store the Rooms as they are found. This allows other Rooms and Doors to use the information when needed.
    The more complex loadRoom() does the real work. It is designed to be re-entrant and uses four parameters:
    nameNT - the name of the next room to look up.
    properties - the filename of the properties file.
    from - the last room/door found that is looking for this room. Use for error messages.
    lookup - the master lookup HashMap for storing rooms found.
The first thing it does is trim the nameNT String to get rid of white space before and after the string.
It then checks to see if this named entry has a class reference. It sets the class to the name of Room.class which would be com.sun.sgs.darkmud.core.Room for this game unless there is a .class property for nameNT. Note, the nameNT for the first room searched for is "room.origin".
The next thing is to look for a name.aliases property. If one is found, the .split() operator is used to parse the property String into a String[ ] array using a comma as the separator as shown in the regex passed into .split().
A Room reference is then setup and set to null. It the attempts to generated a new MudObject of the requested class and provides the aliases for the object as well by calling newMudObject().
The two newMudObject() end up returning a MudObject of a Template using the class requested. this somewhat complex way of doing thing allows you to declare the class as a property string or that's my assumption. What it boils down to is that MudObjects are made by passing an array of aliases to the constructor which are then stored in a HashSet list member, aliasList, of the MudObject.
NOTE: The is no requirement for an object to have aliases.
Next the room's description is read in. All rooms should have descriptions. The room's setDescription() method is called to store the description in the room object.
NOTE: A future change will be to add long descriptions for rooms.
As this point, the room is stored on the lookup list using the name as the key and the object as the value.
Now the inventory of the room is loaded using the String.split() operation as before and sets up a String[ ] array of names.
Inventory objects can be Doors or Items. Items can be anything that's not a door (a passageway) or room (an area) like NPCs, objects, sounds, MOBs, etc.

A Door is Found in Inventory

Assuming that a Door name is in the array, the loadDoor() method is passed the item's name, the properties filename, the name of the room it is in, and the lookup list so that it can be added for future reference.
As with the Room, the Door class is first set up. If no class property, then Door.class.getName() would return com.sun.sgs.darkmud.core.Door for this game.
Then the aliases are collected and the normal and long descriptions are read in.
Unique to Doors is the direction string name. If there is no direction, then the direction is set to "nowhere". So you access a door without a direction by using "go nowhere"? Strange.
The next thing is to load the destination for the Door. Doors can only go to one place, for now anyway, and the destination has to be a Room object.
Now for the recursive part. If the Room name is not on the lookup list, the loadRoom() method is called to load the Room and this can cause use to go through the whole process again.
If this is a good Door that leads to a Room that exists, then create a Door MudObject of the proper class and save the descriptions, direction, and destination room into the Door object.
All done, so return the Door object to the Room caller.
One thing to note, Doors don't have inventories. This could be an area for improvement as keys could be left in doors or special items used to open it.

Final Step for the Room

The valid Door object is added to the Room's inventory and after all of the inventory items have been added, the Room's name is bound to the Room object to be handled as a ManagedObject by the database.

An Item is Found in Inventory

Items are handled similar  to Doors. The loadObject() method is called and passed the item's name, the property filename. and the name of the container (the Room normally).
As with the Rooms and Doors, the class property is checked for and com.sun.sgs.darkmud.core.MudObject is used if no class is set. The aliases are then gather up and the object is created and the descriptions added to the object.
The last step leads to recursion again since Items can have Inventories. Each name in the inventory String[ ] array is turned into an object and added to the Items inventory though a call to addToInventory() and passing an object returned from a recursive call to loadObject().
So, you can have bags within bags. Guns with clips and clips with ammo, etc.

That's it in a nutshell.