The Navajo Document model was introduced to create a language with certain semantic features to communicate with web services. A Navajo Document is used to communicate with business oriented services in the spirit of a true Service Oriented Architecture that is loosely coupled and does not have to deal with a shared domain model between the applications. It is based on the request/response paradigm of the web. It proposes a single language, in comparison to the typical XML Schema approach for defining a new language for each new web service. The Navajo Document model combines data and meta data (simple semantics). The original main purpose of the semantic features was to be able to generate a feature rich user interface for any Navajo Document instance. The first generic 'client' used a simple XSLT script to generate a fully functional HTML user interface with which an entire Service Based application could be used without hand coding any user interface.
This specification defines the Navajo Document Model using its default serialization, XML. Furthermore, the document defines an API for the Navajo Document Model that can be implemented in any programming language, like Java, C#, Objective C, PHP.
.This document describes the specification of the Navajo Document Model or shorthand Navajo Document. Navajo Document is used to model request and response of (Navajo) Web Services using the concept of 'Forms'. The default Navajo Document serialization structure is XML. In this documentation we will the XML representation to explain the Navajo Document Model. Navajo Document is specifically suited for augmenting various data elements with meta data like type and subtype and description. Furthermore, the simplicity of the XML structure enables the use of an easy to use variant of the XPath expression language.
Using Navajo Document you can:
A generated user interface is shown and (part of) its corresponding Navajo Document.
The picture on the left shows a Java SWT generated UI. It was generated using a Navajo Document instance (picture on the right). Depending on the type of the data elements (as defined in the Navajo Document) different UI widgets are used.The Navajo Document Model consists of the following XML elements:
Example The following example shows an Navajo Document as XML (as shown in Fig. 2):
<tml> <header> <transaction rpc_usr="joe" rpc_name="GetClubDetails" rpc_pwd="secret"/> <header> <message name="BVODetails" type="simple"> <property description="Organization Name" direction="in" name="Name" value="Fortuna Sittard" length="" type="string"/> <property description="Start date" direction="in" name="StartDate" value="2009-07-15 10:03:12.444" length="" type="date"/> <property description="Type of organization" direction="in" name="OrganizationType" length="" type="selection" cardinality="+"> <option selected="1" name="SportClub" value="Sports club"/> <option selected="0" name="Facility" value="Sports facility"/> <option selected="0" name="SportStore" value="Sports store"/> <option selected="0" name="SportsFederation" value="Sports federation"/> <property> <property description="Logo" direction="out" subtype="extension=jpg,handle=binary_object562366navajo,mime=image/jpeg" name="Logo" length="46080" type="binary"> /9j/4AAQSkZJRgABAgEASABIAAD/4RpwRXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEAAAEaAAUA AAABAAAAYgEbAAUAAAABAAAAagEoAAMAAAABAAIAAAExAAIAAAAdAAAAcgEyAAIAAAAUAAAAj4dp [...] </tml>A typical client-server Navajo Document web service interaction pattern is the so called Asynchronous Call to a Synchronous Web Service or better a non-blocking synchronous web service call. It means that the client synchronously calls a web service in a specific "web service call"-thread, 'listening' (non-blocking) for the response in a separate thread in order to do something useful with the response. This is similar to an "Ajax" operation in a typical Web "2.0" application.
All data in a Navajo Document is represented as properties. Properties are defined using the property tag. A property can have the following attributes:
Types can be specified within the type attribute of a property. The Navajo Document Model defines a number of different types:
A special type of property is the so called 'selection property'. A selection property can be used to model simple key/value pairs that are typically represented in user interfaces like dropdown lists, selection lists or radio button groups. A property of type 'selection' must have an additional attribute: cardinality. The cardinality of selection property specifies whether a single key/value pair (cardinality="1") or multiple (cardinality="+") key/value pairs may be selected.
NOTE that the names used in this section might be misleading. This is due to legacy and backwards compatibility; the Navajo Document model and its use within the Navajo Service Oriented Framework has evolved since 2002. Actually, the option tag name is called a Selection in the corresponding Navajo Document API! Also the key/value pairs are called name/value pairs in the current version of the Navajo Document Model.
Key/value pairs are modeled using the option tag. An option tag must have the following attributes:
As of this version of the Navajo Document Model the value of an option is typeless. A string value is always assumed.Example
<property name="Choose" type="selection" cardinality="1" direction="in"> <option name="Good" value="3" selected="0"> <option name="Better" value="2" selected="0"> <option name="Best" value="1" selected="1"> <property>
All properties must be grouped within messages. A message can be nested, i.e. it may have a parent message. Messages are defined using the message tag. A message can have the following attributes:
An array message, i.e. a message with type 'array' is used to model a set of complex data, i.e. group of properties and/or messages. An array message consists of a top level array message, defining its name:
<message name="MyArrayMessage" type="array"/>An non-empty array message consists of sub messages (or elements) with exactly the same message/property structure, i.e. each sub message must have the same properties (with possibly different values) and other sub (array) messages (if any). A array message element must have a name that is equal to its top level array message parent. An array message element may have an additional index attribute to indicate an index value, i.e. a unique number among its siblings which can be used for addressing purposes.
Example
<message name="MyArrayMessage" type="array"> <message name="MyArrayMessage"> <property name="Identification" type="string" length="64" description="Unique identifier for this entity" value="A1"/> <property name="RegistrationDate" type="date" value="1978-01-01"/> <message> <message name="MyArrayMessage"> <property name="Identification" type="string" length="64" description="Unique identifier for this entity" value="C2"/> <property name="RegistrationDate" type="date" value="2003-06-09"/> <message> <message name="MyArrayMessage"> <property name="Identification" type="string" length="64" description="Unique identifier for this entity" value="F9"/> <property name="RegistrationDate" type="date" value="1999-03-21"/> <message> <message>
Sometimes it can be convenient, for the sake of bandwidth reduction, to specify the 'structure' of an array message only once instead of repeating property attributes for each array sub message. This can be accomplished by defining a special sub message as the first element of the array message using a special message type called 'definition'.
Example
<message name="MyArrayMessage" type="array"> <message name="MyArrayMessage" type="definition"> <property name="Identification" type="string" length="64" description="Unique identifier for this entity"/> <property name="RegistrationDate" type="date"/> <message> <message name="MyArrayMessage"> <property name="Identification" value="A1"/> <property name="RegistrationDate" value="1978-01-01"/> <message> <message name="MyArrayMessage"> <property name="Identification" value="C2"/> <property name="RegistrationDate" value="2003-06-09"/> <message> <message name="MyArrayMessage"> <property name="Identification" value="F9"/> <property name="RegistrationDate" value="1999-03-21"/> <message> <message>
The main purpose of the Navajo Document Model is to be a communication language with (and between) web services. A Navajo Document serves as input (request) as well as output (response) for a web service. Complex tasks are typically composed of multiple web services that are called in a certain sequence. A well known 'call pattern' is e.g. calling a web service that queries data about some entity, modifying some values and calling a subsequent web service that stores the modified data. The web service interaction pattern may be specified in the Navajo Document to serve as an additional 'hint' for web service clients.
A Navajo Document may specify zero or more subsequent web services that use the current Navajo Document instance as input. These web services are modeled using the methods tag that contains method children tags to specify each web service. The name of the web service is defined in a mandatory name attribute. Example
<methods> <method name="StoreBook"/> <method name="DeleteBook"/> <methods>
A Navajo Document instance contains AT MOST 1 header element. The header element is used to define web service related information, i.e. information that can be used by some web service server provider to identify the user (client) that is calling a web service.
A header contains AT MOST a single transaction element that has the following mandatory attributes:
<header> <transaction rpc_usr="joe" rpc_pwd="mysecret" rpc_name="ShowMe"/> </header>The header may contain additional elements which are relevant in the scope of a particular Navajo Server. For asynchronous web service support a callback tag is introduced. The callback tag contains a reference to an asynchronous component, running as a separate thread in the server, of a web service. This reference can be used in subsequent calls to the same web service in order to implement a 'polling' mechanism. The callback tag may contain 1 or more object tags to address multiple asynchronous server threads. The callback tag is always created by the server. If a web service is requested that contains an asynchronous component, the server will create the callback tag and its object children. Almost all the attributes of an object tag should be controlled by a web service server:
<header> <transaction rpc_usr="joe" rpc_pwd="mysecret" rpc_name="SomeAsyncService"/> <callback> <object perc_ready="0.0" ref="8532343" name="async" finished="false" interrupt=""/> <callback> </header>
Navajo messages and properties can be addresses by using XPath expressions. However, since the Navajo Document Models defines a very strict structure, a much simpler addressing method can be applied.
Messages are addressed either absolutely (using / prefix) or relatively (using ../ or no prefixes):
MessageName := [:string]('@'[:integer]){0,1} MessagePathExpression ::= ( '/'{0,1} | '../'*) MessageName ('/'|'../'MessageName)*Addressing a message will result in getting a 'reference' or a 'pointer' to the addressed message. The '@' notation is used to address message elements of an array message. The identifier after the '@' sign corresponds to the 'index' attribute present in one of the array message element of the address array message. Addressing the 'parent' (../) from within an array message i element will return the parent of the placeholder array message(!).
Properties must be addressed with a Message Path Expression prefix:
PropertyName ::= [:string] PropertyPathExpression ::= MessagePathExpression'/'PropertyNameAddressing a property will result in a reference to the addressed property. Examples
Consider the following Navajo Document instance:
<tml> <message name="SomeMessage"> <property name="FirstProperty" type="string" value="alphabetagamma"/> <message name="MyArrayMessage" type="array"> <message name="MyArrayMessage" index="0"> <property name="Identification" type="string" length="64" description="Unique identifier for this entity" value="A1"/> <property name="RegistrationDate" type="date" value="1978-01-01"/> <message> <message name="MyArrayMessage" index="1"> <property name="Identification" type="string" length="64" description="Unique identifier for this entity" value="C2"/> <property name="RegistrationDate" type="date" value="2003-06-09"/> <message> <message> </message> </tml>Some useful Navajo Path Expressions are (the message/property attribute which is displayed is specified between brackets):
/SomeMessage (name) = 'SomeMessage' /SomeMessage/FirstProperty (value) = 'alphabetagamma' /SomeMessage/MyArrayMessage@1/RegistrationDate (value) = '2003-06-09' /SomeMessage/MyArrayMessage@1/../FirstProperty (value)= 'alphabetagamma'
The purpose of the Navajo Document API is to specify a standard for accessing, modifying and creating Navajo Document XML instances from any programming language. A set of classes is proposed and for each of the classes an interface is specified.
The following interface definitions are introduced:
The Navajo interface is the top level interface. Each Navajo Document instance has a corresponding Navajo object.
interface Navajo { void addHeader(in Header) void addMessage(in Message, [Optional] in boolean overwrite) void addMethod(in Method) Navajo copy() list<Message> getAllMessages() list<Method> getAllMethods() Header getHeader() Message getMessage(in string name) Method getMethod(in string name) Property getProperty(in string name) boolean isEqual(Navajo) }
addHeader()
takes one argument. If a Header object is already
present, it gets overwritten after this method call.addMessage()
takes one or two arguments. The Message will overwrite
an existing sibling message with the same name if the overwrite
argument has the value true
addMethod()
takes one argument. The Method object is appended to a list of
already existing Method objects.copy()
takes zero arguments. The entire Navajo object will get copied and
a new Navajo is returned.getAllMessages()
takes zero arguments. All the 'top level' Message objects
are returned in a list. Top level means messages which have the tml tag as their parent.
getMessage()
takes one argument. The name of the message directly at the 'top level' or a
Navajo path expression pointing to a deeper level message or a array message element.
getMethod()
takes one argument. The name of the method (web service name) is used to look up
the corresponding Method object.
getProperty()
takes one argument. A Navajo path expression is used
to directly address a property.
isEqual()
takes one argument. The current Navajo object is
compared to the Navajo object given as an argument. The method returns the boolean
value true
if the two Navajo objects have the same message
definitions structure with the same property definitions. The same message definitions means, exactly the same
message nesting structure with the same message names and types. The same property
definition means the same value and the same type.
An object implementing the Header interface corresponds to the header part of the Navajo Document Model.
interface Header { void setRPCName(in string webservice) void setRPCPassword(in string password) void setRPCUser(in string username) string getRPCName() string getRPCPassword() string getRPCUser() }
setRPCName()
takes one argument. The webservice
argument sets the rpc_name attribute.getRPCName()
takes zero arguments. The value of the rpc_name attribute is returned.setRPCPassword()
takes one argument. The password
argument is used to set the rpc_pwd attribute.getRPCPassword()
takes zero arguments. The value of the rpc_pwd attribute is returned.setRPCName()
takes one argument. The username
argument is used to set the rpc_usr attribute.getRPCName()
takes zero arguments. The value of the rpc_usr attribute is returned.An object implementing the Message interface corresponds to a message element (including its sub messages) of a Navajo Document instance.
interface Message { void setName(in string messagename) string getName() void setType(in 'simple'|'array'|'definition' type) 'simple'|'array'|'definition' getType() void addMessage(in Message, [Optional] in boolean overwrite) void addElement(in Message) list<Message> getAllMessages() Message getMessage(in string name) Message getParentMessage() void addProperty(in Property) Property getProperty(in string name) list<Property> getAllProperties() }
setName()
takes one argument. The messagename
argument sets the name of the message.getName()
takes zero arguments. It name of the message is returned.setType()
takes one argument. The type
argument sets the type of the message.getType()
takes zero arguments. The type of the message is returned.addMessage()
takes one or two arguments. It adds a message to the current message, i.e. a child
of the current message. If the overwrite
argument is set to true
a sibling with the same name
gets overwritten.
addElement()
takes one argument. It adds an message element to an array message. This
method only work for array messages.getAllMessages()
takes zero arguments. All the 'children' Message objects
are returned in a list. Children means messages that have 'this' message as their parent.
getMessage()
takes one argument. The name of the message directly at the 'top level' or a
Navajo path expression pointing to a deeper level message or a array message element.
getParentMessage()
takes zero messages. Return the 'parent' Message of 'this' message.
addProperty()
takes one argument. It adds a property to 'this' message.getProperty()
takes one argument. It return the Property object corresponding
to the property with has the supplied name
argument as its name.
A Navajo path expression can also be used to address a property that is present
in children messages are array element messages.
getAllProperties()
takes zero arguments. All the 'children' Property objects
are returned in a list. Children means all properties that are directly under 'this' message and
not in any of its 'children' messages.
An object implementing the Property interface corresponds to a property element (including its sub messages) of a Navajo Document instance.
interface Property { void setName(in string propertyname) string getName() void setValue(in object value) object getValue() void setLength(in integer length) integer getLength() void setType(in string type) string getType() void setSubType(in string key, in string value) string getSubType(in string key) string removeSubType(in string key) string getSubTypes() void setCardinality(in '1'|'+' cardinality) string getCardinality() void setDirection(in 'in'|'out' direction) 'in'|'out' getDirection() void setDescription(in string description) string getDescription() void addSelection(in Selection) list<Selection> getAllSelectedSelections() list<Selection> getAllSelections() }
setName()
takes one argument. The propertyname
argument sets the name of the property.getName()
takes zero arguments. The name of the property is returned.setValue()
takes one argument. The value
arguments set the value of the property. The
type is set based upon the object type of the value
argument.getValue()
takes zero arguments. The value of the property is returned.setLength()
takes one argument. The length
argument sets the length of the property.
The length is not relevant for the following types: date, boolean,
clocktime and selection.getLength()
takes zero arguments. The length of the property is returned.setType()
takes one argument. The type
argument sets the type of the property.getType()
takes zero arguments. The type of the property is returned.setSubType()
takes two arguments. The key
and value
arguments set a new key/value pair for the subtype of a
property. If the subtype is non-empty, the new key/value pair is appended with a prefixed ';' character.getSubType()
takes one argument. The value of the given key in the The subtype of the property is returned.removeSubType()
takes one argument. The given key
is removed from the subtype of the property.getSubTypes()
takes zero arguments. The entire subtype of the property is returned.setCardinality()
takes one argument. The cardinality
argument sets the cardinality of a selection type property.getCardinality()
takes zero arguments. The cardinality of a selection type property is returned.setDirection()
takes one argument. The direction
argument sets the direction of the property.getDirection()
takes zero arguments. The direction of the property is returned.setDescription()
takes one argument. The description
argument sets the description of the property.getDescription()
takes zero arguments. The description of the property is returned.addSelection()
takes one argument. Adds a selection option to a selection type property.
If the option name already exists, replace it with the new one.
If the property type is not 'selection', a exception should be thrown.getAllSelectedSelections()
takes zero arguments. All the Selection objects that correspond
to option elements that have the selected attribute set to '1'.getAllSelections()
takes zero arguments. All All the Selection objects that correspond
to option elements are returned.
An object implementing the Selection interface corresponds to an option element of a Navajo Document instance.
interface Selection { void setName(in string name) string getName() void setValue(in string value) string getValue() void setSelected(in boolean selected) boolean isSelected() }
setName()
takes one argument. The argument name
sets the name attribute of an option element.
getName() takes zero arguments. Returns the name attribute of an option element.
setValue()
takes one argument. The argument value
sets the value attribute of an
option element.
getValue()
takes zero arguments. Returns the value attribute of an option element.
setSelected()
takes one argument. The boolean argument selected
sets the
selected attribute of an option element. If the boolean value true
is passed, the selected attribute is set to '1'; if the boolean value false
is passed, selected attribute is set to '0'.
isSelected()
takes zero arguments. Returns true
if
the selected attribute of an option element is set to '1' or false
if it is set to '0'.
An object implementing the Method interface corresponds to an method element of a Navajo Document instance. If a Method object is added to a Navajo object, the methods tag should be created if none is present, otherwise it should be reused.
interface Method { void setName(in string name) string getName() }
setName()
takes one argument. The argument name
sets the name attribute of an method element.
getName()
takes zero arguments. Returns the name attribute of an method element.
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="tml"> <xs:annotation> <xs:documentation>This is the top level tag</xs:documentation> </xs:annotation> <xs:complexType> <xs:sequence> <xs:element maxOccurs="1" minOccurs="1" ref="xtml:header"/> <xs:element maxOccurs="1" minOccurs="0" ref="xtml:methods"/> <xs:choice maxOccurs="unbounded" minOccurs="0"> <xs:element ref="xtml:message"/> </xs:choice> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="header"> <xs:annotation> <xs:documentation>Contains the target Navajo service and username/password information</xs:documentation> </xs:annotation> <xs:complexType> <xs:sequence> <xs:element ref="transaction"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="transaction"> <xs:complexType> <xs:attribute name="rpc_name" type="xs:string" use="required"/> <xs:attribute name="rpc_usr" type="xs:string" use="required"/> <xs:attribute name="rpc_pwd" use="required"/> </xs:complexType> </xs:element> <xs:element name="message"> <xs:annotation> <xs:documentation>A message groups properties and other messages</xs:documentation> </xs:annotation> <xs:complexType> <xs:choice> <xs:element maxOccurs="unbounded" ref="message"/> <xs:element maxOccurs="unbounded" ref="property"/> </xs:choice> <xs:attribute name="name" type="xs:string" use="required"/> <xs:attribute name="type" type="xs:string"/> <xs:attribute name="index" type="xs:integer"/> </xs:complexType> </xs:element> <xs:element name="property"> <xs:annotation> <xs:documentation>A property is the basic data element</xs:documentation> </xs:annotation> <xs:complexType> <xs:sequence> <xs:element maxOccurs="unbounded" minOccurs="0" ref="option"/> </xs:sequence> <xs:attribute name="name" type="xs:string" use="required"/> <xs:attribute name="type" use="required"> <xs:simpleType> <xs:restriction base="xs:NMTOKEN"> <xs:enumeration value="boolean"/> <xs:enumeration value="integer"/> <xs:enumeration value="selection"/> <xs:enumeration value="string"/> <xs:enumeration value="date"/> <xs:enumeration value="float"/> <xs:enumeration value="binary"/> <xs:enumeration value="money"/> <xs:enumeration value="clocktime"/> <xs:enumeration value="stopwatchtime"/> <xs:enumeration value="percentage"/> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute name="value" type="xs:string"/> <xs:attribute name="direction" use="required"> <xs:simpleType> <xs:restriction base="xs:NMTOKEN"> <xs:enumeration value="in"/> <xs:enumeration value="out"/> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute name="length" type="xs:byte"/> <xs:attribute name="cardinality" type="xs:string"/> <xs:attribute name="description" type="xs:string"/> </xs:complexType> </xs:element> <xs:element name="option"> <xs:annotation> <xs:documentation>Used in properties of type selection to define a list of (possibly selected) name/value pairs</xs:documentation> </xs:annotation> <xs:complexType> <xs:attribute name="name" type="xs:string" use="required"/> <xs:attribute name="value" type="xs:string" use="required"/> <xs:attribute name="selected" use="required"> <xs:simpleType> <xs:restriction base="xs:NMTOKEN"> <xs:enumeration value="1"/> <xs:enumeration value="0"/> </xs:restriction> </xs:simpleType> </xs:attribute> </xs:complexType> </xs:element> <xs:element name="methods"> <xs:annotation> <xs:documentation>Links to possible subsequent methods</xs:documentation> </xs:annotation> <xs:complexType> <xs:sequence> <xs:element maxOccurs="unbounded" ref="method"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="method"> <xs:annotation> <xs:documentation>A method location</xs:documentation> </xs:annotation> <xs:complexType> <xs:attribute name="name" type="xs:string" use="required"/> <xs:attribute name="description" type="xs:string" use="required"/> </xs:complexType> </xs:element> </xs:schema>
$Id: NavajoDocument.html,v 1.13 2009/07/15 16:31:56 arjen Exp $