wyvern.kernel.properties
Class ArchetypeManager

java.lang.Object
  extended bywyvern.kernel.properties.ArchetypeManager
All Implemented Interfaces:
WizTypes

public final class ArchetypeManager
extends java.lang.Object
implements WizTypes

This class provides methods for parsing, loading and instantiating archetypes.

An archetype is a list of properties that can be shared by one or more GameObjects. A GameObject refers to its archetype via the parent uplink (getParent()), whose value is the local path to the archetype definition file (e.g. "magic/wand_medium_fireball"). Note that a GameObject is not required to belong to any archetype, but if it does, it inherits the properties of that archetype. Any properties the GameObject has in its local list override identically-named properties in the object's archetype.

When a client calls GameObject.getProperty(), the PList code first checks the object's plist for the property, and if it doesn't find it, it checks for a parent uplink to follow. If it finds an archetype for the object, the PList asks the Archetype manager (this class) to load or find the archetype, and then searches that list for the property.

Archetypes can inherit properties from other archetypes. They do so via a parent uplink, which is a relative path to an archetype file. When PList searches an archetype for a property, if it doesn't find it, it will traverse the ancestor pointers until it finds the property, or until it discovers a top-level archetype with no parent.

To create an instance of an archetype, use ArchetypeImpl.makeInstance(). This looks in the archetype (again, an archetype is a property list) for a "class" property to instantiate. If the class name (the value of the "class" property) is not fully-qualified, it looks in the wyvern.lib.classes package for the class.

Version:
1.0, Jan 25, 1998
Author:
Steve Yegge

Field Summary
static java.lang.String ARCHETYPE_ROOT
           
 
Fields inherited from interface wyvern.lib.WizTypes
ARCH, ELDER, JUNIOR, MAX_LEVEL, MIN_LEVEL, PLAYER, SENIOR, WIZARD
 
Constructor Summary
ArchetypeManager()
           
 
Method Summary
 void addProperties(java.util.List src, PropertyList dest)
          Adds properties from the source list to the dest list, cloning any mutable properties.
 void addProperties(PropertyList dest, org.w3c.dom.Element element)
          Parses a list of externalized properties and adds them to the passed PropertyList.
 void addProperty(java.lang.String name, java.lang.Object value, PropertyList dest)
          Adds a single property (by name) to the destination list.
static void copyProperties(PropertyList arch, PropertyList dest)
          Copies local properties from an archetype to an object.
static boolean discardArchetype(java.lang.String name)
          Discards an archetype from the cache so it can get reloaded from disk after a change.
 java.lang.String fullPathToLocalPath(java.lang.String path)
          Converts a fully-qualified archetype pathname (including filename and, optionally, extension) to a local pathname, e.g.
 Archetype getArchetype(java.lang.String name)
          Gets an Archetype from the system cache, but doesn't load it if it hasn't been loaded yet.
static ArchetypeManager getInstance()
           
static java.lang.String getPythonFilePath(java.lang.Class c)
          Returns the path to the .py file from which a Jython bean property was loaded.
static java.lang.String getPythonFilePath(java.lang.Object ob)
          Returns the path to the .py file from which a Jython bean property was loaded.
static java.lang.String getPythonFilePath(java.lang.String classname)
          Returns the path to the .py file from which a Jython bean property was loaded.
 java.lang.String getRoot()
          Returns the root directory where the archetypes reside.
 GameObject instantiate(Archetype arch)
          Instantiates an archetype by instantiating the class, then setting the new object's parent property to the passed archetype.
 GameObject instantiate(Archetype arch, boolean moveProperties)
          Instantiates an archetype by instantiating the class, then setting the new object's parent uplink to the passed archetype.
 GameObject instantiate(Archetype arch, java.lang.String classname, boolean moveProperties)
          Instantiates an archetype the same way instantiate(arch) does, except that it uses the passed classname, instead of the classname specified in the archetype.
 GameObject instantiate(java.lang.String archname)
          A high-level utility for that loads an archetype, instantiates its class, and initializes the resulting object from the archetype definition.
 GameObject instantiatePyGameObject(java.lang.String path)
          Instantiates a python-based GameObject implementation.
 java.lang.Object instantiatePython(java.lang.String path, java.lang.Class type)
          Instantiates a Python object by loading it from a python file.
static boolean isInstance(GameObject obj, java.lang.String type)
          Returns true if the passed object derives from a specific archetype.
static boolean isInstance(PropertyList obj, java.lang.String type)
          Returns true if the passed object derives from a specific archetype.
 Archetype loadArchetype(java.lang.String name)
          Finds or loads the specified archetype, given its name.
 void moveProperties(Archetype arch, GameObject obj)
          Moves local properties from an archetype to an object.
 Archetype parseArchetype(org.w3c.dom.Element node)
          Parses an XML archetype definition, usually read from a map file.
 Archetype parseArchetypeFile(java.lang.String path, boolean cache)
          Parses an XML archetype definition from any file in the system, given the absolute path to the file.
 GameObject parseInlineObject(org.w3c.dom.Element node)
          Reads an inline object definition from the map file and creates the object.
 GameObject parseInlineObject(java.lang.String path)
          Parses an object, where the object is the only object in an XML file.
 GameObject parseInlineObjectFromXML(java.lang.String xml)
          Same as parseInlineObject, but you pass in the XML, rather than a path to a file on disk.
 Archetype parseMapLocalArchetype(Archetype local, org.w3c.dom.Element node)
          Parses an XML archetype definition when it's a reference to a map-local archetype.
 Archetype parseSystemArchetype(java.lang.String archname)
          Parses the specified system archetype.
 void setContinueOnError(boolean continueOnError)
          Tells the ArchetypeManager object to continue parsing if it encounters an error.
 void setErrorLog(java.lang.String path)
          Tells the ArchetypeManager object to write any errors it finds to the specified logfile.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

ARCHETYPE_ROOT

public static java.lang.String ARCHETYPE_ROOT
Constructor Detail

ArchetypeManager

public ArchetypeManager()
Method Detail

getInstance

public static ArchetypeManager getInstance()

getArchetype

public Archetype getArchetype(java.lang.String name)
Gets an Archetype from the system cache, but doesn't load it if it hasn't been loaded yet.

Parameters:
name - the local path to the archetype file (e.g. terrain/dirt1)
Returns:
the Archetype, or null if it's not loaded

loadArchetype

public Archetype loadArchetype(java.lang.String name)
                        throws java.lang.Exception
Finds or loads the specified archetype, given its name.

Parameters:
name - the local path to the archetype file (e.g. terrain/dirt1)
Returns:
the Archetype
Throws:
java.lang.Exception

parseSystemArchetype

public Archetype parseSystemArchetype(java.lang.String archname)
                               throws java.lang.Exception
Parses the specified system archetype. Puts the resulting Archetype in the system cache. This method is private because we want people to access it via loadArchetype().

Parameters:
archname - the local path to the archetype file, e.g. "wiz/mickey/beanstalk".
Returns:
the Archetype, which is loaded and cached
Throws:
java.lang.Exception

parseArchetypeFile

public Archetype parseArchetypeFile(java.lang.String path,
                                    boolean cache)
                             throws java.lang.Exception
Parses an XML archetype definition from any file in the system, given the absolute path to the file.

Parameters:
path - the full pathname, including the file extension.
cache - true to put it in the system archetype cache
Returns:
the Archetype, if it parsed properly.
Throws:
java.lang.Exception

fullPathToLocalPath

public java.lang.String fullPathToLocalPath(java.lang.String path)
Converts a fully-qualified archetype pathname (including filename and, optionally, extension) to a local pathname, e.g. "/games/wyvern/arch/objects/mirror.arch" to "objects/mirror".

Only trims ".arch" extension, not ".py". Handles archetypes and python classes in the wiz/ subtree correctly.

Parameters:
path - the full path
Returns:
the local path

parseArchetype

public Archetype parseArchetype(org.w3c.dom.Element node)
                         throws java.lang.Exception
Parses an XML archetype definition, usually read from a map file. Used by the MapLoader. Wizards normally won't need to call this method.

Parameters:
node - DOM Element representing the archetype
Returns:
an (anonymous) Archetype created from the XML definition. It is not placed in the system cache.
Throws:
java.lang.Exception

parseMapLocalArchetype

public Archetype parseMapLocalArchetype(Archetype local,
                                        org.w3c.dom.Element node)
                                 throws java.lang.Exception
Parses an XML archetype definition when it's a reference to a map-local archetype.

Parameters:
local - the map-local archetype we're referencing
node - the DOM element representing the object
Returns:
an anonymous Archetype created from the XML definition, whose parent is the map-local archetype. It is not placed in the system cache.
Throws:
java.lang.Exception

addProperties

public void addProperties(PropertyList dest,
                          org.w3c.dom.Element element)
                   throws java.lang.Exception
Parses a list of externalized properties and adds them to the passed PropertyList. Used primarily by the MapLoader.

Parameters:
dest - a PropertyList to which to add the properties.
element - a DOM Element that has a property list, i.e. a map header, an archetype, or a bean.
Throws:
java.lang.Exception

addProperties

public void addProperties(java.util.List src,
                          PropertyList dest)
                   throws java.lang.Exception
Adds properties from the source list to the dest list, cloning any mutable properties. Normally you don't need to do this, but the MapLoader uses it for various things.

Parameters:
src - a list of Property objects
dest - a PropertyList (e.g. a GameObject) of some sort
Throws:
java.lang.Exception

addProperty

public void addProperty(java.lang.String name,
                        java.lang.Object value,
                        PropertyList dest)
                 throws java.lang.Exception
Adds a single property (by name) to the destination list. If the value is a MutableProperty, clones it first.

Parameters:
name - the property name
value - the property value
dest - the destination plist
Throws:
java.lang.Exception

instantiate

public GameObject instantiate(java.lang.String archname)
                       throws java.lang.Exception
A high-level utility for that loads an archetype, instantiates its class, and initializes the resulting object from the archetype definition.

Parameters:
archname - the archetype to load (e.g. "spells/medium_fireball")
Returns:
an instance of the archetype
Throws:
java.lang.Exception

instantiate

public GameObject instantiate(Archetype arch)
                       throws java.lang.Exception
Instantiates an archetype by instantiating the class, then setting the new object's parent property to the passed archetype. Does not copy any of the archetype's local properties to the new object, but does clone any mutable properties and gives the object local copies of those.

Parameters:
arch - the archetype to instantiate
Returns:
the new object
Throws:
java.lang.Exception

instantiate

public GameObject instantiate(Archetype arch,
                              boolean moveProperties)
                       throws java.lang.Exception
Instantiates an archetype by instantiating the class, then setting the new object's parent uplink to the passed archetype.

Parameters:
arch - the archetype to instantiate
moveProperties - true to move the archetype's properties to the object. The general rule is: if the archetype is a system archetype (meaning it's defined in its own archetype file in a system or wizard directory), you don't need to move the properties - this function will clone and copy and mutable props from the system archetype. If it's an "anonymous" archetype, such as one created manually, or read in from a map file with some extra properties, you should move them.

Note: this is a destructive operation - the archetype will wind up empty, with no properties left after this call, if moveProperties is true.

Throws:
java.lang.Exception

instantiate

public GameObject instantiate(Archetype arch,
                              java.lang.String classname,
                              boolean moveProperties)
                       throws java.lang.Exception
Instantiates an archetype the same way instantiate(arch) does, except that it uses the passed classname, instead of the classname specified in the archetype. This is a fairly special-purpose method that you're not likely to need.

Parameters:
classname - a classname fully-qualified exactly the way it would appear in the "class" attribute of an archetype header. Python classnames are relative to the wyvern root dir, and end with ".py".
arch - the archetype to instantiate
moveProperties - true to move the local properties from the archetype to the object; usually only useful if the archetype is anonymous, e.g. it was parsed from a map file.
Returns:
the new object
Throws:
java.lang.Exception

moveProperties

public void moveProperties(Archetype arch,
                           GameObject obj)
                    throws java.lang.Exception
Moves local properties from an archetype to an object.

Parameters:
arch - the archetype to use
obj - the object to use
Throws:
java.lang.IllegalArgumentException - if you pass in a system archetype, or any other exception we might hit
java.lang.Exception

copyProperties

public static void copyProperties(PropertyList arch,
                                  PropertyList dest)
                           throws java.lang.Exception
Copies local properties from an archetype to an object. Clones any mutable properties during the copy.

Parameters:
arch - the archetype to use (works for any PropertyList, though)
dest - the object to use
Throws:
java.lang.IllegalArgumentException - if you pass in a system archetype, or any other exception we might hit
java.lang.Exception

instantiatePyGameObject

public GameObject instantiatePyGameObject(java.lang.String path)
                                   throws java.lang.Exception
Instantiates a python-based GameObject implementation. This is just a convenience wrapper that calls instantiatePython(filename, GameObject.class) - check the instantiatePython() docs for more info.

Parameters:
path - the absolute or relative path to a python file, e.g. "wiz/rhialto/python/foo.py" or "/games/wyvern/wiz/rhialto/python/foo.py". The method assumes that if the path starts with "/", it's an absolute path.
Returns:
the instantiated GameObject
Throws:
java.lang.Exception

instantiatePython

public java.lang.Object instantiatePython(java.lang.String path,
                                          java.lang.Class type)
                                   throws java.lang.Exception
Instantiates a Python object by loading it from a python file.

You can get the path to the python file that was used for loading a particular python object by calling one of the getPythonFilePath() methods. Additionally, if type parameter to instantiatePython() is PropertyList.class, or a subclass of PropertyList (including GameObject and its sub-interfaces and implementation classes), then the returned object will be tagged with a "@python" PList property holding the relative path of the python file.

Parameters:
path - the absolute or relative path to a python file, e.g. "wiz/rhialto/python/foo.py" or "/games/wyvern/wiz/rhialto/python/foo.py". The method assumes that if the path starts with "/", it's an absolute path.
type - an instance of the java class which the python class inherits from. You need to pass this if you're going to cast the returned object into a Java class or interface. Required because of some complexities in the Jython software. You can cast the return value to an instance of this class. If you pass null, you'll be stuck with treating it as an Object.
Returns:
the instantiated object, which can be used (by casting) as whatever class you passed in for the type.
Throws:
an - exception if jython couldn't parse it, or it's not an instance of the passed type.
java.lang.Exception

parseInlineObject

public GameObject parseInlineObject(java.lang.String path)
                             throws java.lang.Exception
Parses an object, where the object is the only object in an XML file.

Parameters:
path - the absolute path to the file
Returns:
the GameObject, created by calling the version of ArchetypeManager.parseInlineObject() that takes a DOM node as its argument.
Throws:
any - exception, if the object couldn't be parsed or instantiated, or its properties couldn't be added properly. If continueOnError is set, then it'll return a partially-instantiated object (or null, if it really couldn't do anything) instead of throwing an exception.
java.lang.Exception

parseInlineObjectFromXML

public GameObject parseInlineObjectFromXML(java.lang.String xml)
                                    throws java.lang.Exception
Same as parseInlineObject, but you pass in the XML, rather than a path to a file on disk.

Parameters:
xml - the xml to parse
Throws:
java.lang.Exception

parseInlineObject

public GameObject parseInlineObject(org.w3c.dom.Element node)
                             throws java.lang.Exception
Reads an inline object definition from the map file and creates the object. This has different results from doing:
   Archetype arch = ArchetypeManager.parseArchetype();
   GameObject obj = arch.instantiate();
 
Calling arch.instantiate() instantiates the class, then sets the parent uplink to point to the archetype. This method, in comparison, instantiates the class, and then moves the properties from the archetype to the GameObject's local property list. If you want the properties to be in the object's local list, this is the correct method to use.

Parameters:
node - the DOM element representing the object
Returns:
the object, initialized with any sub-props from the element Returns null if continueOnError is set and the object couldn't be parsed/instantiated.
Throws:
any - exception if continueOnError is false, and any error was encountered during parsing.
java.lang.Exception

getRoot

public java.lang.String getRoot()
Returns the root directory where the archetypes reside.


discardArchetype

public static boolean discardArchetype(java.lang.String name)
Discards an archetype from the cache so it can get reloaded from disk after a change.

Parameters:
name - the full archetype path, e.g. "monsters/demon/grug"
Returns:
true if the archetype was in the cache

isInstance

public static boolean isInstance(GameObject obj,
                                 java.lang.String type)
Returns true if the passed object derives from a specific archetype. Looks up the object's archetype-inheritance chain to see if the passed archetype is one of the parent archetypes for the object.

Note: GameObjects implement the PropertyList interface, so calling this method is the same as calling ArchetypeManager.isInstance(PropertyList, String). This version is just a convenience wrapper that calls that version.

Parameters:
type - the path to the archetype, e.g. "objects/treasure/coins" or "wiz/foobar/misc/quest_item".
obj - the object to check.
Returns:
true if the object inherits from the archetype

isInstance

public static boolean isInstance(PropertyList obj,
                                 java.lang.String type)
Returns true if the passed object derives from a specific archetype. Looks up the object's archetype-inheritance chain to see if the passed archetype is one of the parent archetypes for the object.

Parameters:
obj - the property list to check (a GameObject or Archetype)
type - the path to the archetype, e.g. "objects/treasure/coins" or "wiz/foobar/misc/quest_item".
Returns:
true if the object inherits from the archetype

setContinueOnError

public void setContinueOnError(boolean continueOnError)
Tells the ArchetypeManager object to continue parsing if it encounters an error. Normally the ArchetypeManager will throw an exception and stop parsing if it discovers an error when parsing an object definition from an XML file. In some cases, such as parsing player files, we want to keep loading the object even if we find errors.


setErrorLog

public void setErrorLog(java.lang.String path)
Tells the ArchetypeManager object to write any errors it finds to the specified logfile.

Parameters:
path - a logfile path that starts with "wiz/" for wiz logs, or if it doesn't start with "wiz/", it'll be placed in the system logfile path, which is unreadable by wizards.
Throws:
java.lang.IllegalArgumentException - if the path is invalid

getPythonFilePath

public static java.lang.String getPythonFilePath(java.lang.Object ob)
Returns the path to the .py file from which a Jython bean property was loaded. Only works if the Jython class was loaded as a bean property, not if it was loaded by some other mechanism.

Parameters:
ob - a python object
Returns:
the relative path to the file, or null if not found in our cache

getPythonFilePath

public static java.lang.String getPythonFilePath(java.lang.Class c)
Returns the path to the .py file from which a Jython bean property was loaded. Only works if the Jython class was loaded as a bean property, not if it was loaded by some other mechanism.

Parameters:
c - the class of a python object, obtained from ob.getClass()
Returns:
the relative path to the file, or null if not found in our cache

getPythonFilePath

public static java.lang.String getPythonFilePath(java.lang.String classname)
Returns the path to the .py file from which a Jython bean property was loaded. Only works if the Jython class was loaded as a bean property, not if it was loaded by some other mechanism.

Parameters:
classname - the classname of a jython bean property.

This is typically in the form "org.python.proxies.main$myclass$num", where "$num" (e.g. "$24") is the instance number. If there's an instance number found in the class name, this method will ignore it when looking up the path, so that all python instances loaded from the same file will share the same cache entry.

The short version is: you probably don't have to worry about it; this method will try to figure out the right thing to do, regardless of what classname you pass in. But it's probably easier to call the version of this method that takes an object.

Returns:
the relative path to the file, or null if not found in our cache