United eWay tWSDL: Types API
The tWSDL Types Component will likely be one of the largest. The Types Component API will be used to define types, to create instances of a given type and to verify that an instance conforms to the type definition.

The Types API will closely follow the method of type construction in XML Schema, where complex types are composed (built up from) other complex types and of simple types. Simple types are restrictions of built-in primitive types.

Defining A Type
In XML Schema a type has

Built in types, also known as primitive types, have a special namespace, and do not have a base type. User defined types can use any other namespace, so that the user defined type could have the same name as a primitive type without creating a conflict. The definition of a type is somewhat complicated. There are a number of methods of defining a type. The tWSDL Type Component will support many, but not all of these methods. One API procedure will be needed for each method of defining a type. Here is a list of the most useful methods:

Primitive Types
The tWSDL Type Component will be seeded with built-in primitive types. The function of the API which adds a new primitive type to the system is to map the prefix:name to a validation procedure. Every type will have a validation procedure, the name of which is based upon the namespace and name of the type. The primitive type API is a simplified version of the simpleType API. Most of the work in building up primitive types will be in the validation procedure. A number of these are already completed, including the most difficult ones dealing with times, dates and durations.

# call with typeNamespace, typeName, validation code, description

::wsdl::types::primitiveType::new tcl anySimpleType {return 1} \
 {Base type, should return true for every case}

# then the following should return 1 in every case:

::wsdb::types::tcl::anySimpleType::validate "My String Always Valid"

# Assumes that newPrimitiveType places primitive types in a namespace called 'tcl'

 
Simple Types (simpleTypes)
All simpleTypes are based upon a restriction of either another simpleType or of a primitive type. There will be three APIs for creating simpleTypes. All three APIs require a type namespace and a type name. In the simpleType APIs, the type namespace is an alias, analogous to a prefix in an XML namespace. There will be a map to associate an alias to the formal namespace. In the examples below the type namespace, or alias will be 'vs'.

proc ::wsdl::types::simpleType::new {typeNamespace typeName baseType} {...}

# call with type namespace, type name, base type

::wsdl::types::simpleType::new "vs" numbers xsd::integer

# Note that this simply aliases the type xsd::integer calling it 'numbers'

# You call the validation code by reference:

$::wsdb::types::vs::numbers::validate 8

 

Restriction by Enumeration:


proc ::wsdl::types::simpleType::restrictByEnumeration {typeNamespace typeName baseType enumerationList} {...}
# call with typeNamespace, typeName, baseType and enumerated list of possible values:

::wsdl::types::simpleType::restrictByEnumeration "vs" someNumbers vs::numbers {5 6 7 8 9} 

# The following should return false (0):

$::wsdb::types::vs::someNumbers::validate 10

 

Restriction by Pattern


::proc ::wsdl::types::simpleType::restrictionByPattern {typeNamespace typeName baseType pattern} {...}

# Call with typeNamespace, typeName baseType and regular expression:

::wsdl::types::simpleType::restrictionByPattern vs guid xsd::string {
[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}}

# use the type variable for validation:

$::wsdb::types::vs::guid::validate 92ab783d-9303-571F-AC32-03bAcD9671F1

 

Notice that in order to validate a simple type, you use the value of the variable validate. When a new simpleType is created, a Tcl namespace is defines which at minimum contains the variable validate which references a procedure which handles the validation. This allows the developer to use any previously written Tcl procedure, the only restriction is that the procedure must return 1 if the data is valid and 0 otherwise. Complex type validation follows an similar pattern except that the validation procedure takes a reference to the complexType (Tcl namespace).

Building up Complex Types
Once a simpleType has been added to the Type Component, it can be used in the construction of a complexType. In tWSDL, a complexType is a series of particles. A particle is a type with the added information of the minimum occurances, maximum occurances and something called the term. In the API, a term is a reference to the typeName including the typeNamespace.
Model Groups
A model group specifies the composition of elements used to define a complexType type. The division into choice, sequence and all are based more on procedural language constructs and data storage issues than actual data model details. In tWSDL, all elements are stored the same regardless of the model group. Therefore, some of the restrictions detailed in XML Schema can be safely ignored.
Model Group Sequence and All
Model Group All implies that each particle can occur at most once. In many procedural languages this implies that an associative array could be used for storage without the need to worry about name collisions. Model Group Sequence is restricted to being an ordered list of particles, each particle occuring zero or more times, but all particles of a given type must be arranged consecutively. The procedural language reason for this is to ensure very rapid access to the initial particle of a given type by narrowing the range of possible start indexes. It is probably unnecessary to require this intrepretation in tWSDL, and there is no reason to force particles to be serialized in a particular order within an element. Although the tWSDL server can handle a sequence in any order, it produces sequences in the required order.
Model Group Choice
Model Group Choice can be thought of as the complexType equivalent of enumeration. However, Choice leaves open the possibility of different base types. I'm not sure it is a great thing to have a single type name containing different actual types. At present, tWSDL does not support Model Group Choice.
Mapping Between an XML Schema Type and tWSDL API

The following is an example of how to approach the construction of an API to build up a type based upon the XML fragment representing the type.

Restriction by Enumeration:


<s:simpleType name="CreditCardTypeCode">
 <s:restriction base="xsd:string">
  <s:enumeration value="Visa" />
  <s:enumeration value="Mastercard" />
  <s:enumeration value="AmericanExpress" />
  <s:enumeration value="Discover" />
  <s:enumeration value="DinersClub" />
 </s:restriction>
</s:simpleType>
 

This simpleType can be create via the following API call:


::wsdl::types::simpleType::restrictByEnumeration vs CreditCardTypeCode xsd::string {
 "Visa"  
 "Mastercard"
 "AmericanExpress"
 "Discover"
 "DinersClub" 
}
 

Notice that the 'vs' type namespace (prefix/alias) is not shown in the WSDL file because vs is the targetNamespace, and uses the prefix 'tns' in the WSDL file.

Restriction by Pattern:


<s:simpleType name="guid">
  <restriction base="xsd:string">
    <pattern value="[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}" />
  </s:restriction>
</s:simpleType>

 

This simpleType can be create via the following API call:


::wsdl::types::simpleType::restrictByPattern vs guid xsd::string \
    {[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}};
 

Model Group Sequence:


<xsd:complexType name="DonorDataResponse">
 <xsd:sequence>
   <xsd:element minOccurs="0" maxOccurs="1" name="Result" type="tns:DonorData" />
   <xsd:element minOccurs="0" maxOccurs="1" name="Source" type="xsd:string" />
   <xsd:element minOccurs="0" maxOccurs="20" name="ErrorMessageList" type="tns:ErrorString" />
   <xsd:element minOccurs="0" maxOccurs="1" name="StackTrace" type="xsd:string" />
 </xsd:sequence>
</xsd:complexType>
 

The DonorDataResponse would be defined in the following way:

::wsdl::elements::modelGroup::sequence::new vs DonorDataResponse {
    {Result:elements::vs::DonorData {minOccurs 0}}
    {Source {minOccurs 0}}
    {ErrorMessageList:vs::ErrorString {minOccurs 0 maxOccurs 20}}
    {StackTrace {minOccurs 0}}
} 

# Note1: When the base type is xsd:string, 
#  you do not need to include any type information.
#
# Note2: If the base type namespace is XML Schema (xsd prefix), 
#  you do not need to include the prefix (xsd::dateTime = dateTime)
# Note3: when the base type is a complexType, 
#  you have to prefix the base type with 'elements::'
#  The referenced base complexType must exists prior to use.

 

Model Group Sequence (Extend complexType) [Note: Unimplimented]:


<xsd:complexType name="DirectBillDonationPaymentData">
 <xsd:complexContent mixed="false">
   <xsd:extension base="tns:DonationPaymentData">
     <xsd:sequence>
       <xsd:element minOccurs="1" maxOccurs="1" name="StartDate" type="xsd:dateTime" />
       <xsd:element minOccurs="0" maxOccurs="1" name="BillingAddress" type="tns:AddressData" />
     </xsd:sequence>
   </xsd:extension>
 </xsd:complexContent>
</xsd:complexType>
 

::wsdl::elements::modelGroup::sequence::extendSequence vs\
  "DirectBillDonationPaymentData"\
  "elements::vs::DonationPaymentData" \
{
  {StartDate:dateTime}
  {BillingAddress:vs::AddressData {minOccurs 0}}
}
 

Note: Extending a sequence is not supported, but here are some ideas: