Skip to content

Type Loaders

Gary edited this page Mar 10, 2015 · 2 revisions

Table of Contents

A type loader reads a type definition file and stores type information in metadata class objects like DomNodeType for access by the rest of the DOM and performs other functions like associating types with DOM adapters.

ATF provides the type loader base class XmlSchemaTypeLoader, which is also called a schema type loader, because it uses an XML Schema for its type definition. If you use some other type definition language, you must implement your own type loader, but you may be able to modify XmlSchemaTypeLoader to use your type definition format.

Functions of the Type Loader

An ATF type loader does the following:

The type loader creates an XmlSchemaTypeCollection object, which is a collection of metadata class objects (DomNodeType, ChildInfo, and AttributeInfo) associated with an XML schema file. These metadata objects encapsulate most of the information in the type definition file and provide it in a form usable to the DOM.

Your application can create its own schema type loader class derived from XmlSchemaTypeLoader, conventionally called SchemaLoader.

XmlSchemaTypeLoader and XmlSchemaTypeCollection objects can be used to read and write XML data representing application data. For further information, see DOM Persistence.

Creating Metadata Class Objects

One of the primary functions of XmlSchemaTypeLoader is to create metadata objects from the type definition, using the DomNodeType, AttributeInfo, and ChildInfo classes described in DomNodes and DOM Metadata Classes. Types defined by the XML schema map directly to the DOM metadata objects the type loader creates.

Examining the ATF Simple DOM Editor Sample shows the correspondence between the schema definitions and metadata objects. First, here's the type definition for "eventType":

<!--Event, with name, start time, duration and a list of resources-->
<xs:complexType name ="eventType">
  <xs:sequence>
    <xs:element name="resource" type="resourceType" maxOccurs="unbounded"/>
  </xs:sequence>
  <xs:attribute name="name" type="xs:string"/>
  <xs:attribute name="time" type="xs:integer"/>
  <xs:attribute name="duration" type="xs:integer"/>
</xs:complexType>

This sample has a Schema class that contains a subclass for each type in the data definition. Each of these subclasses has fields for the metadata objects created by the type loader from the types in the type definition file. Here's the class for "eventType":

public static class eventType
{
    public static DomNodeType Type;
    public static AttributeInfo nameAttribute;
    public static AttributeInfo timeAttribute;
    public static AttributeInfo durationAttribute;
    public static ChildInfo resourceChild;
}

See how the metadata objects flow from the schema definition:

  • The DomNodeType Type for the type "eventType" itself. XmlSchemaTypeLoader creates a DomNodeType for every <xs:complexType> in the schema.
  • An AttributeInfo for each attribute:
    • nameAttribute for "name".
    • timeAttribute for "time".
    • durationAttribute for "duration".
  • The ChildInfo resourceChild for the "resourceType" objects that can be children of objects of "eventType".
This class Schema is very useful for referring to the metadata class objects generated by the type loader and is produced by the DomGen utility.

Using the DomGen Utility to Create a Schema Class

DomGen is an ATF DOM utility that generates a schema class from an XML schema file. This schema class, usually named Schema, contains references to all the metadata classes that the type loader creates from the type definition. The schema class also contains an Initialize() method that initializes all the references to the actual values from the metadata classes the type loader created.

As will be seen, these references to metadata classes are needed for various DOM operations. For example, property data can be stored in DomNodeType objects to facilitate viewing application data attributes in a property editor. For more information on this use, see DOM Property Descriptors.

In using the DOM, you often need to obtain references to metadata classes, and you could do this by calling XmlSchemaTypeCollection methods. For example, this statement gets the DomNodeType object corresponding to the type named "keyType":

DomNodeType keyType = typeCollection.GetNodeType("keyType");

GetNodeType() requires supplying the name of the type as a string. If this string is wrong or changes, the code still compiles correctly, so the error is not detected until runtime.

Instead, you could use a metadata class from the schema class to get the DomNodeType. For example, the ATF Timeline Editor Sample uses DomGen, which generates a class named keyType for the "keyType" type:

public static class keyType
{
    public static DomNodeType Type;
    public static AttributeInfo startAttribute;
    public static AttributeInfo descriptionAttribute;
    public static AttributeInfo specialEventAttribute;
}

You could now rewrite the above statement as:

DomNodeType keyType = keyType.Type;

Using metadata classes from the schema class allows type checking to be done at compile time by isolating the usage of the string literal to the code generated by DomGen, while the rest of the application references the type safe metadata classes. If the application uses the wrong name for the metadata class names, the error is likely detected at compile time.

The ATF Using Dom Sample uses DomGen to create its schema class GameSchema from an XML Schema. For a description of precisely what DomGen produces in this sample, see UsingDom Data Model. The UsingDom sample is very useful for understanding DomGen, type loaders, and DOM concepts in general, because it uses the DOM in a basic, straightforward fashion.

Type Loader Example

The type loader GameSchemaLoader in the ATF Using Dom Sample illustrates the basics. First, it derives from XmlSchemaTypeLoader:

public class GameSchemaLoader : XmlSchemaTypeLoader

GameSchemaLoader's constructor loads the type definition file game.xsd, which is an XML Schema:

public GameSchemaLoader()
{
    // set resolver to locate embedded .xsd file
    SchemaResolver = new ResourceStreamResolver(Assembly.GetExecutingAssembly(), "UsingDom/Schemas");
    Load("game.xsd");
}

Your application should construct the type loader object some time during its initialization. You can make the SchemaLoader class a MEF component, so its instantiation is handled for you, and this is what most of the ATF samples do.

After the schema is loaded, the base class XmlSchemaTypeLoader calls OnSchemaSetLoaded(), which is overridden in the sample:

protected override void OnSchemaSetLoaded(XmlSchemaSet schemaSet)
{
    foreach (XmlSchemaTypeCollection typeCollection in GetTypeCollections())
    {
        m_namespace = typeCollection.TargetNamespace;
        m_typeCollection = typeCollection;
        GameSchema.Initialize(typeCollection);
        ...

GetTypeCollections() simply gets the XmlSchemaTypeCollection instance, which was created by loading the type definition file and contains type information from the type definitions.

GameSchema is the schema class generated by DomGen in this sample. OnSchemaSetLoaded() calls GameSchema.Initialize() with the XmlSchemaTypeCollection instance. GameSchema.Initialize() uses this XmlSchemaTypeCollection instance to set the references to the values of the metadata class objects the loader created, as in these lines:

public static void Initialize(XmlSchemaTypeCollection typeCollection)
{
    gameType.Type = typeCollection.GetNodeType("gameType");
    gameType.nameAttribute = gameType.Type.GetAttributeInfo("name");
    gameType.gameObjectChild = gameType.Type.GetChildInfo("gameObject");
    ...

Here's the definition of the gameType class, which defines these gameType fields of metadata class objects:

public static class gameType
{
    public static DomNodeType Type;
    public static AttributeInfo nameAttribute;
    public static ChildInfo gameObjectChild;
}

Thus, the first line of Initialize() calls XmlSchemaTypeCollection.GetNodeType() to get the DomNodeType for the type "gameType" and places the reference to it in gameType.Type. Similarly, the second line sets a reference to an AttributeInfo for the "name" attribute, and the third a reference to the ChildInfo for children of this type of node.

Creating Metadata Objects without a Type Loader

You could create metadata objects manually without a type loader, but it's much easier to derive a type loader from XmlSchemaTypeLoader. For an example of creating metadata objects from the ATF Simple DOM No XML Editor Sample, see Defining Data Model Without an XML Schema. This is useful to study any way, because it shows the kind of work the type loader does.

Topics in this section

Clone this wiki locally