mirror of
https://github.com/moparisthebest/xeps
synced 2024-12-03 22:42:16 -05:00
3696d0809b
git-svn-id: file:///home/ksmith/gitmigration/svn/xmpp/trunk@3564 4b5297f7-1745-476d-ba37-a9c6900126ab
1820 lines
80 KiB
XML
1820 lines
80 KiB
XML
<?xml version='1.0' encoding='UTF-8'?>
|
|
<!DOCTYPE xep SYSTEM 'xep.dtd'
|
|
[ <!ENTITY % ents SYSTEM "xep.ent"> %ents;
|
|
<!ENTITY xmlrpc "XML-RPC<note><link url='http://www.xmlrpc.org/spec'>The XML-RPC Specification</link></note>">
|
|
]
|
|
>
|
|
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
|
|
<xep>
|
|
<header>
|
|
<title>Jabber Object Access Protocol (JOAP)</title>
|
|
<abstract>The Jabber Object Access Protocol, or JOAP, defines a
|
|
mechanism for creating Jabber-accessible object servers, and
|
|
manipulating objects provided by those servers. It is intended
|
|
for development of business applications with Jabber.</abstract>
|
|
&LEGALNOTICE;
|
|
<number>0075</number>
|
|
<status>Deferred</status>
|
|
<type>Standards Track</type>
|
|
<sig>Standards</sig>
|
|
<dependencies>None</dependencies>
|
|
<supersededby>None</supersededby>
|
|
<supersedes>None</supersedes>
|
|
<shortname>N/A</shortname>
|
|
<author>
|
|
<firstname>Evan</firstname>
|
|
<surname>Prodromou</surname>
|
|
<email>evan@prodromou.san-francisco.ca.us</email>
|
|
<jid>EvanProdromou@jabber.org</jid>
|
|
</author>
|
|
<revision>
|
|
<version>0.3</version>
|
|
<date>2003-05-22</date>
|
|
<initials>esp</initials>
|
|
<remark>For consistency, renamed hyphenated elements
|
|
'new-address' and 'return-type' to 'newAddress' and 'returnType'
|
|
respectively. Added 'desc' element for human-readable
|
|
descriptions to object servers and classes. Changed the
|
|
'writeable' [sic] attribute to the more correct
|
|
'writable'. Added experimental namespace recommendation in
|
|
XMPP Registrar section.</remark>
|
|
</revision>
|
|
<revision>
|
|
<version>0.2</version>
|
|
<date>2003-03-05</date>
|
|
<initials>esp</initials>
|
|
<remark>Added a schema and DTD, a number of new examples, and
|
|
ensured that all examples validate against the DTD and
|
|
schema.</remark>
|
|
</revision>
|
|
<revision>
|
|
<version>0.1</version>
|
|
<date>2003-01-28</date>
|
|
<initials>esp</initials>
|
|
<remark>Initial version (unpublished).</remark>
|
|
</revision>
|
|
</header>
|
|
<section1 topic='Introduction'>
|
|
<p>This document defines the Jabber Object Access Protocol (JOAP)
|
|
as an extension to the Jabber protocol. It outlines the
|
|
addressing scheme and IQ stanzas that comprise the protocol as
|
|
well as the data types that the protocol models. Example
|
|
applications are discussed, as well as security
|
|
considerations.</p>
|
|
<p>Jabber has a number of attractive features that give it an
|
|
advantage over existing frameworks for building multi-tier
|
|
applications, such as the Simple Object Access Protocol (SOAP)
|
|
or Java 2, Enterprise Edition (J2EE). Among these are:</p>
|
|
<ul>
|
|
<li><strong>Built-in authentication.</strong> All clients in the
|
|
Jabber network must be authenticated with their server before
|
|
sending messages to other Jabber entities. Inter-server
|
|
communication requires additional authentication, in the form
|
|
of dialback connections or other trust mechanisms. This
|
|
ensures that, when a message is delivered to a JOAP object
|
|
server, there is little doubt as to the authenticity of its
|
|
originator.</li>
|
|
<li><strong>Global namespace.</strong> Jabber allows namespacing
|
|
of addresses according to domain names. This allows objects to
|
|
be accessed globally, according to authorization rules.</li>
|
|
<li><strong>An asynchronous messaging model.</strong> Jabber is
|
|
built on a store-and-forward mechanism that allows a single
|
|
client to send messages to multiple servers concurrently. Of
|
|
course, synchronous messaging can be simulated on the client
|
|
side.</li>
|
|
<li><strong>Cross-enterprise messaging.</strong> Jabber is
|
|
designed to allow cross-enterprise messaging. Using Jabber for
|
|
multitier applications makes development of cross-enterprise
|
|
systems as easy as intra-enterprise development.</li>
|
|
<li><strong>Message routing.</strong> The architecture of Jabber
|
|
is based on clients that connect to a local server, and then
|
|
can send messages through that server to other clients,
|
|
servers, or components. Topographically, this contrasts well
|
|
with the one-to-one connections required with, for example,
|
|
HTTP.</li>
|
|
<li><strong>Factoring network connections out of
|
|
scalability.</strong> Because messages in Jabber are routed,
|
|
components need to maintain only one connection -- to their
|
|
upstream Jabber server. This removes the number of network
|
|
connections from the scalability equation for object
|
|
servers.</li>
|
|
<li><strong>Language independence.</strong> Jabber protocol
|
|
implementations exist for Java, C, and C++ as well as a number
|
|
of scripting languages such as Perl and Python.</li>
|
|
<li><strong>Platform independence.</strong> The Jabber protocol
|
|
is implemented on most major modern platforms.</li>
|
|
</ul>
|
|
<p>For existing Jabber development efforts, there are significant
|
|
advantages to building applications within a JOAP
|
|
framework. It should go without saying that, for developers creating
|
|
business applications on top of Jabber, a uniform object access
|
|
protocol provides significant advantage for cross-product
|
|
integration.</p>
|
|
<p>In addition, implementers of special-purpose components, such as
|
|
multi-user chat servers or whiteboarding components, can use an
|
|
object-server interface to allow fine-grained control of the
|
|
implementations, especially where such control is not specified
|
|
by the applicable Jabber protocol.</p>
|
|
</section1>
|
|
<section1 topic='Requirements'>
|
|
<p>JOAP has the following design goals:</p>
|
|
<ul>
|
|
<li>Create a protocol for client programs to access object
|
|
server components.</li>
|
|
<li>Create a model for addressing object servers, classes, and
|
|
instances.</li>
|
|
<li>Define a language for manipulating data.</li>
|
|
<li>Define a language for describing data structures.</li>
|
|
<li>Maintain compatibility with &xep0009;.</li>
|
|
<li>Make classes and instances directly addressable.</li>
|
|
<li>Allow human- and programming-language independence.</li>
|
|
<li>Allow easy dynamic mapping of JOAP classes to local classes
|
|
in Perl, Python, and other dynamic languages.</li>
|
|
</ul>
|
|
<p>The following are non-goals:</p>
|
|
<ul>
|
|
<li>Enable object-oriented access to all parts of the Jabber
|
|
network (e.g., clients, other components).</li>
|
|
<li>Define a language for creating or altering classes on an
|
|
object server.</li>
|
|
<li>Define a language for describing or defining the
|
|
authorization of given users for given objects.</li>
|
|
<li>Define a programming interface between object servers and
|
|
classes in those servers (like Enterprise Java Beans).</li>
|
|
</ul>
|
|
</section1>
|
|
<section1 topic='Overview'>
|
|
<p>The JOAP interface is made up of three key parts:</p>
|
|
<ul>
|
|
<li>A scheme for defining the addresses of object servers,
|
|
classes, and instances (collectively known as
|
|
"objects").</li>
|
|
<li>A set of message stanzas in the <tt>jabber:iq:joap</tt>
|
|
namespace for manipulating data in object servers, classes,
|
|
and instances. The stanzas allow client programs to analyze
|
|
the structure of objects, to read object attributes, to edit
|
|
object attributes, to add new instances, to delete instances,
|
|
and to search classes.</li>
|
|
<li>An application of XEP-0009 for calling methods on
|
|
objects.</li>
|
|
</ul>
|
|
</section1>
|
|
<section1 topic='Entities in the JOAP Universe'>
|
|
<p>This section describes the various entities in the JOAP
|
|
universe. Some entities are directly addressable with Jabber IDs
|
|
(JIDs), as described below. Others are not considered outside of
|
|
their enclosing entities.</p>
|
|
<section2 topic='Object Server Component'>
|
|
<p>An object server component is a Jabber component that
|
|
provides object services. It is addressed like any other
|
|
Jabber component, i.e., with a DNS hostname or
|
|
pseudo-hostname. Some examples would be:</p>
|
|
<ul>
|
|
<li><tt>payroll.example.com</tt> - A payroll application
|
|
server.</li>
|
|
<li><tt>jukebox.example.com</tt> - An MP3 jukebox server.</li>
|
|
</ul>
|
|
<p>An object server has zero or more attributes, methods, and
|
|
classes.</p>
|
|
</section2>
|
|
<section2 topic='Class'>
|
|
<p>A class is a category of object instances. It defines the
|
|
structure and interface of these instances. Each class is
|
|
addressed using the class name as the node identifier, and the
|
|
object server as the domain identifier. Class names must
|
|
conform to the node identifier restrictions defined for
|
|
XMPP. Class names must also be unique, regardless of case,
|
|
within an object server.</p>
|
|
<p>For example:</p>
|
|
<ul>
|
|
<li><tt>Employee@payroll.example.com</tt> - An employee class
|
|
at the payroll.example.com server.</li>
|
|
<li><tt>Song@jukebox.example.net</tt> - A song class on the
|
|
jukebox server.</li>
|
|
<li><tt>Board@circuit-design.example.com</tt> - A class for
|
|
circuit boards.</li>
|
|
<li><tt>Board@surf-shop.example.net</tt> - A class for
|
|
surfboards -- distinct from above class!</li>
|
|
</ul>
|
|
<p>Beside uniqueness and XMPP compliance, no further requirements are
|
|
made on class names. However, good design suggests mnemonic names.</p>
|
|
<p>Classes define the attributes and methods of their instances. In
|
|
addition, they can have attributes and methods of their own. Finally,
|
|
classes can have superclasses, which indicate an inheritance structure
|
|
as well as implementation of a defined interface.</p>
|
|
<p>JOAP allows for no relative addressing of classes. Classes
|
|
are always referred to by their full address (node identifier
|
|
plus domain identifier).</p>
|
|
</section2>
|
|
<section2 topic='Instance'>
|
|
<p>An instance is a collection of data with identity, state, and
|
|
behavior. Each instance is a member of a class, which defines the
|
|
attributes (data) and methods (behavior) of the instance
|
|
itself.</p>
|
|
<p>An instance is addressed using the node plus server that identifies
|
|
its class, as well as a unique string that occupies the resource
|
|
identifier section of the Jabber ID. The resource is only unique over
|
|
the space of the corresponding class. Some example instance addresses:</p>
|
|
<ul>
|
|
<li><tt>Room@hotel.example.com/103</tt> - Room 103 in the
|
|
Example Hotel.</li>
|
|
<li><tt>Element@periodic-table.example.net/103</tt> - Element
|
|
103 (rutherfordium) in the periodic table.</li>
|
|
<li><tt>Employee@payroll.example.com/JohnSmith</tt> - An
|
|
employee named "John Smith".</li>
|
|
<li><tt>Customer@videorental.example.net/JohnSmith</tt> - A
|
|
customer named "John Smith" (not necessarily the
|
|
same person as the above employee!).</li>
|
|
</ul>
|
|
<p>Besides uniqueness within a class, and compliance with the
|
|
rules for resource identifiers in the XMPP standard, there are
|
|
no further requirements on instance identifiers in JOAP. In
|
|
particular, the instance identifier is opaque -- that is, no
|
|
further information about the state of the object can or
|
|
should be discerned from the identifier. What visible part of
|
|
the instance, if any, makes up the unique resource identifier
|
|
is implementation dependent.</p>
|
|
<p>That said, it is recommended that the instance identifier be
|
|
persistent through the life of the instance. In addition, using
|
|
mnemonic identifiers can greatly enhance the usability of JOAP
|
|
objects.</p>
|
|
<p>As with other resource identifiers, instance identifiers are
|
|
case-sensitive.</p>
|
|
<p>The instance identifier roughly corresponds to a primary key in a
|
|
relational database, and for object servers that provide access to
|
|
relational databases, it is recommended to use the primary key of a
|
|
table as the instance identifier. For tables with a compound key, a
|
|
comma (',') dash ('-'), or other non-alphanumeric character can be
|
|
used to separate parts of the key for better readability. For
|
|
example:</p>
|
|
<ul>
|
|
<li><tt>Date@calendar.example.net/2003-01-26</tt> -- The date
|
|
January 26th, 2003.</li>
|
|
<li><tt>City@canada.example.com/Montréal,QC</tt> -- The city
|
|
of Montréal, in the province of Québec.</li>
|
|
</ul>
|
|
<p>JOAP allows for no relative addressing of
|
|
instances. Instances are always referred to using their full
|
|
address (node identifier plus domain identifier plus resource
|
|
identifier).</p>
|
|
</section2>
|
|
<section2 topic='Attribute'>
|
|
<p>An attribute is a unit of state that makes up part of an object
|
|
server, instance, or class. Each attribute has a name and a
|
|
type.</p>
|
|
<p>Attribute names must be strings of characters containing only
|
|
the characters [a-zA-Z0-9_]. The first character must be an
|
|
underscore or alphabetic character. <note>This requirement is
|
|
intended to allow easy mapping of attributes in JOAP to
|
|
attributes of objects in client programming languages. The
|
|
restriction is the lowest common denominator for variable
|
|
names in most modern programming languages.</note></p>
|
|
<p>Attributes cannot be addressed individually. Attributes are
|
|
manipulated by sending JOAP messages to the object that owns
|
|
them.</p>
|
|
</section2>
|
|
<section2 topic='Method'>
|
|
<p>A method is a unit of behavior that makes up part of an
|
|
object. Methods in JOAP are compatible with &xmlrpc;, as
|
|
specified in &xep0009;. In particular, methods have a name, a
|
|
return type, and 0 or more parameters, each of which has a
|
|
type.</p>
|
|
<p>The one exception to XML-RPC compatibility is that method
|
|
names for JOAP are restricted to the characters
|
|
[a-zA-z0-9_]. <note>This is to avoid conceptual mismatch in
|
|
programming languages where the other three characters allowed
|
|
by XML-RPC, namely ".", ":", and
|
|
"/", are used to separate class or instance names
|
|
from methods.</note></p>
|
|
<p>Methods cannot be directly addressed using JOAP. Methods are
|
|
described and executed by sending messages to the object
|
|
server, class, or instance that owns them.</p>
|
|
</section2>
|
|
</section1>
|
|
<section1 topic='JOAP Data Types'>
|
|
<p>The range of JOAP data types is borrowed directly from
|
|
XML-RPC.</p>
|
|
<section2 topic='Scalar Types'>
|
|
<p>The scalar types include the following:</p>
|
|
<ul>
|
|
<li><strong>int</strong> or <strong>i4</strong>: a 32-bit
|
|
signed integer</li>
|
|
<li><strong>boolean</strong>: a one-digit integer representing
|
|
"true" (1) or "false" (0)</li>
|
|
<li><strong>string</strong>: a string of characters</li>
|
|
<li><strong>double</strong>: double-precision signed
|
|
floating-point number</li>
|
|
<li><strong>datetime.iso8601</strong>: a date value, in ISO
|
|
8601 format</li>
|
|
<li><strong>base64</strong>: binary data, base64-encoded for
|
|
transmission</li>
|
|
</ul>
|
|
</section2>
|
|
<section2 topic='Instance Addresses'>
|
|
<p>Instance addresses are a special type of string used for
|
|
referring to instance objects. They can be passed as
|
|
parameters to methods, or set as attribute values.</p>
|
|
<p>If a value can contain an object instance, its type is the
|
|
address of a class. The address of any object instance that is
|
|
an instance of that class, or any of its subclasses, can be
|
|
used in that value.</p>
|
|
<p>For example, if <tt>Boxcar@trainset.example.com</tt> is a
|
|
subclass of <tt>Car@trainset.example.com</tt>, then
|
|
<tt>Boxcar@trainset.example.com/569</tt> can be used as a
|
|
method parameter, or set as an attribute, where
|
|
<tt>Car@trainset.example.com</tt> is the defined type.</p>
|
|
<p>Because addresses are used for instance values, all methods
|
|
involving instances are implicitly pass-by-reference. If a
|
|
pass-by-value functionality is needed, a struct (see below)
|
|
should be used instead.</p>
|
|
<p>Note that attribute and method param types can use classes
|
|
and instances from other object servers (that is, with
|
|
different domain identifiers). For instance, an
|
|
<tt>Employee@payroll.example.com</tt> class could have an
|
|
attribute of type <tt>Job@hr.example.com</tt>.</p>
|
|
</section2>
|
|
<section2 topic='Compound Types'>
|
|
<p>There are two compound types defined in XML-RPC.</p>
|
|
<section3 topic='Arrays'>
|
|
<p>An <em>array</em> is an ordered list of values. An array
|
|
can contain values of any type, including other compound
|
|
types.</p>
|
|
<p>In JOAP, as with XML-RPC, it is not possible to address,
|
|
set, or delete elements of an array. To set values in an
|
|
array, the entire new array must be specified.</p>
|
|
</section3>
|
|
<section3 topic='Structs'>
|
|
<p>A <em>struct</em> is a set of name-value pairs organized into
|
|
a logical grouping. A struct can contain values of any type,
|
|
including other compound types.</p>
|
|
<p>In JOAP, as with XML-RPC, it is not possible to address,
|
|
set, or delete elements of a struct. To set values in an
|
|
struct, the entire new struct must be specified.</p>
|
|
<p>Structs are useful mainly for groupings of data that do not
|
|
have independent identity or behavior. Where an object
|
|
needs identity or behavior, an instance should be used
|
|
instead of a struct.</p>
|
|
</section3>
|
|
</section2>
|
|
<section2 topic='Specifying Types'>
|
|
<p>Types are specified by a string name of the type. This can be
|
|
one of the XML-RPC types described above, or a class
|
|
address.<note>Implementers can determine if a specified type
|
|
is valid by checking it against a list of the XML-RPC
|
|
types. If it does not match, it should be checked to see if
|
|
matches the syntax for a class address (node identifier
|
|
plus domain identifier). Otherwise, it is not a valid
|
|
type.</note></p>
|
|
</section2>
|
|
</section1>
|
|
<section1 topic='JOAP Stanzas'>
|
|
<p>This section defines the Jabber stanzas that make up the JOAP
|
|
protocol.</p>
|
|
<p>Each stanza is an information query (IQ). Except for method
|
|
calls, the stanzas are all in the 'jabber:iq:joap' namespace. Each
|
|
of the following sections describes a stanza in that namespace,
|
|
herein called a "verb". The verbs allow basic access
|
|
to object servers, classes, and instances.</p>
|
|
<p>Not all verbs can be sent to all JOAP entities. The appropriate JOAP
|
|
entity a verb should be addressed to is noted under the description of
|
|
the verb.</p>
|
|
<section2 topic='<describe>'>
|
|
<p>The <describe> verb requests the interface -- that is, methods,
|
|
attributes, and classes -- of a given object server or class. The IQ
|
|
type is "get".</p>
|
|
<p>The <describe> verb is useful for creating wrapper
|
|
classes in JOAP clients, either at runtime or at compile
|
|
time. It can also be used for object browsers, or for client
|
|
programs to ascertain that the interface they assume for an
|
|
object is still valid.</p>
|
|
<section3 topic='Targets'>
|
|
<p><describe> verbs can be sent to object servers, classes, and
|
|
instances. Each will return different data.</p>
|
|
<ul>
|
|
<li>Object servers return zero or more descriptive texts,
|
|
zero or more attribute definitions, zero or more method
|
|
definitions, zero or more class names, and a
|
|
timestamp.</li>
|
|
<li>Classes return zero or more descriptive texts, zero or
|
|
more attribute definitions, zero or more method
|
|
definitions, and a timestamp.</li>
|
|
<li>Instances return the exact results of sending the
|
|
<describe> method to their class. This is for convenience
|
|
only; it is preferable to send <describe> to the class
|
|
directly.</li>
|
|
</ul>
|
|
</section3>
|
|
<section3 topic='Descriptive Texts'>
|
|
<p>Each object description can contain one or more strings of
|
|
descriptive text. This is to indicate the
|
|
purpose and usage of the object in human-readable form.</p>
|
|
<p>Multiple descriptions are allowed in the hope that they
|
|
will be used to describe the attribute in multiple
|
|
languages (differentiated using the xml:lang
|
|
attribute).</p>
|
|
</section3>
|
|
<section3 topic='Attribute Definitions'>
|
|
<p>Attribute definitions have the following parts:</p>
|
|
<ul>
|
|
<li>A name, which is a legal attribute name as described
|
|
above.</li>
|
|
<li>A type, which is a legal JOAP type as described
|
|
above.</li>
|
|
<li>A flag indicating if the attribute is an attribute of the
|
|
class itself, or of individual instances.</li>
|
|
<li>A flag indicating if the attribute is writable.</li>
|
|
<li>A flag indicating if the attribute is required.</li>
|
|
<li>One or more strings of descriptive text, to indicate the
|
|
purpose and usage of this attribute. Multiple
|
|
descriptions are allowed in the hope that they will be
|
|
used to describe the attribute in multiple languages
|
|
(differentiated using the 'xml:lang' attribute).</li>
|
|
</ul>
|
|
<p>The attribute definitions returned to a client should
|
|
include only attributes the user is authorized to access.</p>
|
|
</section3>
|
|
<section3 topic='Method Definitions'>
|
|
<p>Method definitions have the following parts:</p>
|
|
<ul>
|
|
<li>A name, which is a legal method name as described
|
|
above.</li>
|
|
<li>A return type, which is a legal JOAP type as described
|
|
above.</li>
|
|
<li>A flag indicating if the method is a method of the class
|
|
itself, or of individual instances.</li>
|
|
<li>Zero or more parameters, each of which has a name, a
|
|
type, and one or more strings of descriptive text.</li>
|
|
<li>One or more strings of descriptive text, indicating the
|
|
use and behavior of this method.</li>
|
|
</ul>
|
|
<p>The method definitions returned to a client should
|
|
include only methods the user is authorized to access.</p>
|
|
</section3>
|
|
<section3 topic='Class References'>
|
|
<p>Classes, in superclass definitions and object server
|
|
interfaces, are always referred to by their full
|
|
address.</p>
|
|
</section3>
|
|
<section3 topic='Timestamps'>
|
|
<p>The timestamp is a date-time value in ISO 8601 format,
|
|
UTC. The timestamp indicates the last time an interface was
|
|
changed, if that information is available.</p>
|
|
</section3>
|
|
<section3 topic='Superclasses'>
|
|
<p>The main point of describing the superclasses a class has
|
|
is to allow clients to make typing distinctions: that is, to
|
|
determine if a class presents a given interface, or may be
|
|
provided as a parameter or attribute in another JOAP
|
|
call.</p>
|
|
<p>The list of superclasses given in a class description is
|
|
flat, not hierarchical. No provision is made to
|
|
indicate which of a class's superclasses are superclasses of
|
|
each other, nor is there any implied precedence order in the
|
|
order of the classes in the returned description.</p>
|
|
<p>In addition, no provision is made to define which
|
|
superclass actually implements any methods or attributes
|
|
defined.</p>
|
|
</section3>
|
|
<section3 topic='Flattening'>
|
|
<p>When a class receives a <describe> verb, it must
|
|
return all its superclasses, including multiple
|
|
ancestors. It must as well return all the attributes and
|
|
methods that it responds to, including those defined in
|
|
its superclasses. This is called a "flattened"
|
|
description of the class. <note>Flattening the class
|
|
interface reduces the need for making multiple
|
|
"describe" verb calls just to find the interface
|
|
for one class.</note></p>
|
|
</section3>
|
|
<section3 topic='Examples'>
|
|
<p>The following examples illustrate the use of the <describe>
|
|
verb. <note>All extended examples in this document refer
|
|
to a particular object domain, based on a fictional model
|
|
train set. A UML description of the object domain is
|
|
available in Appendix D.</note></p>
|
|
<p>To describe a server, the JOAP client sends this
|
|
stanza.</p>
|
|
<example caption='Describing An Object Server'><![CDATA[
|
|
<iq type='get'
|
|
id='joap_describe_1'
|
|
from='Client@example.com'
|
|
to='trainset.example.com'>
|
|
<describe xmlns='jabber:iq:joap' />
|
|
</iq>]]></example>
|
|
<p>The object server returns this response:</p>
|
|
<example caption='Description of an Object Server'><![CDATA[
|
|
<iq type='result'
|
|
id='joap_describe_1'
|
|
from='trainset.example.com'
|
|
to='Client@example.com'>
|
|
<describe xmlns='jabber:iq:joap'>
|
|
<desc xml:lang='en-US'>
|
|
This server provides classes for managing a virtual
|
|
remote train set.
|
|
</desc>
|
|
<attributeDescription writable='true'>
|
|
<name>logLevel</name>
|
|
<type>i4</type>
|
|
<desc xml:lang='en-US'>Verbosity level for access logging.</desc>
|
|
</attributeDescription>
|
|
<methodDescription>
|
|
<name>startLogging</name>
|
|
<returnType>boolean</returnType>
|
|
<desc xml:lang='en-US'>Start logging activity on this
|
|
server. Returns true for success and false for an
|
|
error.</desc>
|
|
</methodDescription>
|
|
<methodDescription>
|
|
<name>stopLogging</name>
|
|
<returnType>boolean</returnType>
|
|
<desc xml:lang='en-US'>Stop logging activity on this
|
|
server. Returns true for success and false for an
|
|
error.</desc>
|
|
</methodDescription>
|
|
<class>Train@trainset.example.com</class>
|
|
<class>Car@trainset.example.com</class>
|
|
<class>Caboose@trainset.example.com</class>
|
|
<class>Engine@trainset.example.com</class>
|
|
<class>Boxcar@trainset.example.com</class>
|
|
<class>PassengerCar@trainset.example.com</class>
|
|
<class>Building@trainset.example.com</class>
|
|
<class>TrackSegment@trainset.example.com</class>
|
|
<class>Switch@trainset.example.com</class>
|
|
<class>Station@trainset.example.com</class>
|
|
<timestamp>2003-01-07T20:08:13Z</timestamp>
|
|
</describe>
|
|
</iq>]]></example>
|
|
<p>To describe the <tt>Car@trainset.example.com</tt> class,
|
|
the JOAP client sends this stanza to the class for
|
|
boxcars.</p>
|
|
<example caption='Describing a Class'><![CDATA[
|
|
<iq type='get'
|
|
id='joap_describe_2'
|
|
from='Client@example.com'
|
|
to='Boxcar@trainset.example.com' >
|
|
<describe xmlns='jabber:iq:joap' />
|
|
</iq>]]></example>
|
|
<p>The class returns this stanza to the JOAP client.</p>
|
|
<example caption='Description of a Class'><![CDATA[
|
|
<iq type='result'
|
|
id='joap_describe_2'
|
|
from='Boxcar@trainset.example.com'
|
|
to='Client@example.com'>
|
|
<describe xmlns='jabber:iq:joap'>
|
|
<desc xml:lang='en-US'>
|
|
A Car in the trainset that can be used to ship cargo.
|
|
</desc>
|
|
<attributeDescription writable='false' required='true'>
|
|
<name>trackingNumber</name>
|
|
<type>i4</type>
|
|
<desc xml:lang='en-US'>Tracking number for this car.</desc>
|
|
</attributeDescription>
|
|
<attributeDescription writable='true' required='true'>
|
|
<name>contents</name>
|
|
<type>string</type>
|
|
<desc xml:lang='en-US'>Contents of the boxcar.</desc>
|
|
</attributeDescription>
|
|
<methodDescription allocation='class'>
|
|
<name>nextTrackingNumber</name>
|
|
<returnType>i4</returnType>
|
|
<desc xml:lang='en-US'>The next available tracking number.</desc>
|
|
</methodDescription>
|
|
<superclass>Car@trainset.example.com</superclass>
|
|
<timestamp>2003-01-07T20:08:13Z</timestamp>
|
|
</describe>
|
|
</iq>]]></example>
|
|
<p>To describe an instance, the JOAP client sends this stanza
|
|
to a particular track segment.</p>
|
|
<example caption='Describing an Instance'><![CDATA[
|
|
<iq type='get'
|
|
id='joap_describe_3'
|
|
from='Client@example.com'
|
|
to='TrackSegment@trainset.example.com/134' >
|
|
<describe xmlns='jabber:iq:joap' />
|
|
</iq>
|
|
]]>
|
|
</example>
|
|
<p>The instance returns this stanza to the JOAP client.</p>
|
|
<example caption='Description of an Instance'><![CDATA[
|
|
<iq type='result'
|
|
from='TrackSegment@trainset.example.com/134'
|
|
to='Client@example.com'
|
|
id='joap_describe_3'>
|
|
<describe xmlns='jabber:iq:joap'>
|
|
<desc xml:lang='en-US'>
|
|
A length of track in the trainset which can be
|
|
connected to a previous and next length of track.
|
|
</desc>
|
|
<attributeDescription>
|
|
<name>previous</name>
|
|
<type>TrackSegment@trainset.example.com</type>
|
|
<desc>Previous segment of track.</desc>
|
|
</attributeDescription>
|
|
<attributeDescription>
|
|
<name>next</name>
|
|
<type>TrackSegment@trainset.example.com</type>
|
|
<desc>Next segment of track.</desc>
|
|
</attributeDescription>
|
|
<timestamp>2003-01-07T20:08:13Z</timestamp>
|
|
</describe>
|
|
</iq>]]>
|
|
</example>
|
|
</section3>
|
|
</section2>
|
|
<section2 topic='<read>'>
|
|
<p>The <read> verb allows clients to retrieve the values
|
|
of attributes of an object server, class, or instance. The
|
|
client can specify which attributes to return; if no
|
|
attributes are specified, then all attributes are
|
|
returned. <note>This allows clients to cheaply retrieve
|
|
meta-information about an instance that may have exceptionally
|
|
large data, such as bin64-encoded file data.</note></p>
|
|
<p>The <read> verb uses the "get" IQ type.</p>
|
|
<section3 topic='Timestamps'>
|
|
<p>A timestamp, in ISO 8601 format, UTC, can be added to the
|
|
results of a <read>. The timestamp indicates the last
|
|
time any of an object's attribute values have changed (not
|
|
just the requested ones). The timestamp can be used, for
|
|
example, to implement object caching on the client side.</p>
|
|
</section3>
|
|
<section3 topic='Error Codes'>
|
|
<p>The following are some common error codes may be generated
|
|
in response to a <read> verb.</p>
|
|
<ul>
|
|
<li><strong>404 (Not Found)</strong>: The object addressed
|
|
does not exists.</li>
|
|
<li><strong>403 (Forbidden)</strong>: The user is not
|
|
authorized to read attributes of this object, or not
|
|
authorized to read the specified attributes of this
|
|
object.</li>
|
|
<li><strong>406 (Not Acceptable)</strong>: The client sent
|
|
an <read> verb specifying attributes that are not
|
|
defined for the class.</li>
|
|
</ul>
|
|
</section3>
|
|
<section3 topic='Examples'>
|
|
<p>This section gives some examples of using the <read>
|
|
verb.</p>
|
|
<p>A client would send the following stanza to an instance to
|
|
read its attributes:</p>
|
|
<example caption='Reading the Attributes of an
|
|
Instance'><![CDATA[
|
|
<iq type='get'
|
|
id='joap_read_1'
|
|
from='Client@example.com'
|
|
to='Station@trainset.example.com/Paddington'>
|
|
<read xmlns='jabber:iq:joap' />
|
|
</iq>
|
|
]]>
|
|
</example>
|
|
<p>In return, the instance would send this stanza to the
|
|
client:</p>
|
|
<example caption='Attributes of an Instance'><![CDATA[
|
|
<iq type='result'
|
|
id='joap_read_1'
|
|
from='Station@trainset.example.com/Paddington'
|
|
to='Client@example.com'>
|
|
<read xmlns='jabber:iq:joap'>
|
|
<attribute>
|
|
<name>name</name>
|
|
<value>Paddington Station</value>
|
|
</attribute>
|
|
<attribute>
|
|
<name>size</name>
|
|
<value>
|
|
<struct>
|
|
<member>
|
|
<name>length</name>
|
|
<value><i4>4</i4></value>
|
|
</member>
|
|
<member>
|
|
<name>width</name>
|
|
<value><i4>3</i4></value>
|
|
</member>
|
|
</struct>
|
|
</value>
|
|
</attribute>
|
|
<attribute>
|
|
<name>previous</name>
|
|
<value>TrackSegment@trainset.example.com/334</value>
|
|
</attribute>
|
|
<attribute>
|
|
<name>next</name>
|
|
<value>TrackSegment@trainset.example.com/271</value>
|
|
</attribute>
|
|
</read>
|
|
</iq>]]>
|
|
</example>
|
|
<p>To read only specified attributes of an instance, the
|
|
client would send this stanza:</p>
|
|
<example caption='Reading Limited Attributes'><![CDATA[
|
|
<iq type='get'
|
|
id='joap_read_2'
|
|
from='Client@example.com'
|
|
to='Train@trainset.example.com/38'>
|
|
<read xmlns='jabber:iq:joap'>
|
|
<name>location</name>
|
|
<name>cars</name>
|
|
</read>
|
|
</iq>
|
|
]]>
|
|
</example>
|
|
<p>In return, the instance would send this stanza to the
|
|
client:</p>
|
|
<example caption='Limited Attributes'><![CDATA[
|
|
<iq type='result'
|
|
id='joap_read_2'
|
|
from='Train@trainset.example.com/38'
|
|
to='Client@example.com'>
|
|
<read xmlns='jabber:iq:joap'>
|
|
<attribute>
|
|
<name>location</name>
|
|
<value>Station@trainset.example.com/Paddington</value>
|
|
</attribute>
|
|
<attribute>
|
|
<name>cars</name>
|
|
<value>
|
|
<array>
|
|
<data>
|
|
<value>Engine@trainset.example.com/14</value>
|
|
<value>PassengerCar@trainset.example.com/112</value>
|
|
<value>PassengerCar@trainset.example.com/309</value>
|
|
<value>BoxCar@trainset.example.com/212</value>
|
|
<value>Caboose@trainset.example.com/9</value>
|
|
</data>
|
|
</array>
|
|
</value>
|
|
</attribute>
|
|
</read>
|
|
</iq>]]></example>
|
|
</section3>
|
|
</section2>
|
|
<section2 topic='<add>'>
|
|
<p>The <add> verb is used to create a new instance of a
|
|
JOAP class. The verb is sent to the JOAP class, which returns
|
|
the address of the newly-created instance.</p>
|
|
<p>Within each <add> verb the client must include
|
|
attribute values for each required, writable attribute of the
|
|
class.</p>
|
|
<p>The IQ is of type "set".</p>
|
|
<section3 topic='Error Codes'>
|
|
<p>The following are some common error codes may be generated
|
|
in response to an <add> verb.</p>
|
|
<ul>
|
|
<li><strong>404 (Not Found)</strong>: The class for which an
|
|
instance is to be instantiated does not exists.</li>
|
|
<li><strong>403 (Forbidden)</strong>: The user is not
|
|
authorized to instantiate an instance of this class.</li>
|
|
<li><strong>405 (Not Allowed)</strong>: The client sent an
|
|
<add> verb to something that isn't a class.</li>
|
|
<li><strong>406 (Not Acceptable)</strong>: The client sent an
|
|
<add> verb containing attributes that are not
|
|
writable, or without all required, writable attributes,
|
|
or with attributes that are not defined for the class, or
|
|
with attribute values that are of the wrong type.</li>
|
|
</ul>
|
|
</section3>
|
|
<section3 topic='Examples'>
|
|
<p>To create a new PassengerCar, the client would send the
|
|
following stanza to the PassengerCar class:</p>
|
|
<example caption='Adding a New Instance'><![CDATA[
|
|
<iq type='set'
|
|
id='joap_add_1'
|
|
to='PassengerCar@trainset.example.com'
|
|
from='Client@example.com'>
|
|
<add xmlns='jabber:iq:joap'>
|
|
<attribute>
|
|
<name>passengers</name>
|
|
<value><i4>38</i4></value>
|
|
</attribute>
|
|
</add>
|
|
</iq>]]></example>
|
|
<p>The class would return the following response:</p>
|
|
<example caption='A New Instance'><![CDATA[
|
|
<iq type='result'
|
|
id='joap_add_1'
|
|
from='PassengerCar@trainset.example.com'
|
|
to='Client@example.com'>
|
|
<add xmlns='jabber:iq:joap'>
|
|
<newAddress>PassengerCar@trainset.example.com/866</newAddress>
|
|
</add>
|
|
</iq>
|
|
]]></example>
|
|
<p>Note that the class created a new instance identifier, 866,
|
|
for the new instance. Further communications from the client
|
|
would use the full instance address returned.</p>
|
|
</section3>
|
|
</section2>
|
|
<section2 topic='<edit>'>
|
|
<p>The <edit> verb is used to update the attributes of an
|
|
object. The name and new value of each attribute that is to be
|
|
updated is listed in the <edit> verb.</p>
|
|
<p>The IQ is of type "set".</p>
|
|
<p>Leaving a given attribute out of an <edit> verb does
|
|
not indicate that the attribute should be set to an undefined
|
|
or default value. The new values of attributes that are left
|
|
out is implementation-dependent; in general, though, they
|
|
should remain unchanged, if possible.</p>
|
|
<section3 topic='Content in <edit> Results'>
|
|
<p>If the results of an <edit> verb have content, it
|
|
will contain the new address of the instance that was
|
|
updated. The new address should be used henceforth by the
|
|
client. <note>This is to allow updates that alter the unique
|
|
key or attribute of an instance that determine its instance
|
|
identifier.</note></p>
|
|
</section3>
|
|
<section3 topic='Error Codes'>
|
|
<p>The following error codes may be generated in response to a
|
|
<edit> verb.</p>
|
|
<ul>
|
|
<li><strong>404 (Not Found)</strong>: The object to be
|
|
edited does not exists.</li>
|
|
<li><strong>403 (Forbidden)</strong>: The user is not
|
|
authorized to edit this object, or to change one of the
|
|
attributes specified in the <edit> request.</li>
|
|
<li><strong>406 (Not Acceptable)</strong>: The client sent
|
|
an <edit> verb containing attributes that are not
|
|
defined for the class, or with attribute values that are
|
|
of the wrong type, or with attribute values that are
|
|
outside the range for the attribute.</li>
|
|
</ul>
|
|
</section3>
|
|
<section3 topic='Examples'>
|
|
<p>To change the number of passengers in a PassengerCar, the
|
|
client would send the following stanza to the instance:</p>
|
|
<example caption='Editing an Instance'><![CDATA[
|
|
<iq type='set'
|
|
id='joap_edit_1'
|
|
from='Client@example.com'
|
|
to='PassengerCar@trainset.example.com/199'>
|
|
<edit xmlns='jabber:iq:joap'>
|
|
<attribute>
|
|
<name>passengers</name>
|
|
<value><i4>31</i4></value>
|
|
</attribute>
|
|
</edit>
|
|
</iq>
|
|
]]></example>
|
|
<p>The client would return the following stanza:</p>
|
|
<example caption='Results of Editing an Instance'><![CDATA[
|
|
<iq type='result'
|
|
id='joap_edit_1'
|
|
to='Client@example.com'
|
|
from='PassengerCar@trainset.example.com/199'>
|
|
<edit xmlns='jabber:iq:joap' />
|
|
</iq>
|
|
]]></example>
|
|
<p>If a client wanted to change the name of a Building, it
|
|
would send the following stanza to the instance:</p>
|
|
<example caption='Editing an Instance'><![CDATA[
|
|
<iq type='set'
|
|
id='joap_edit_2'
|
|
from='Client@example.com'
|
|
to='Building@trainset.example.com/JonesFamilyHome'>
|
|
<edit xmlns='jabber:iq:joap'>
|
|
<attribute>
|
|
<name>name</name>
|
|
<value>Smith Family Home</value>
|
|
</attribute>
|
|
</edit>
|
|
</iq>
|
|
]]></example>
|
|
<p>The results would be as follows:</p>
|
|
<example caption='Results of Editing an Instance'><![CDATA[
|
|
<iq type='result'
|
|
id='joap_edit_2'
|
|
to='Client@example.com'
|
|
from='Building@trainset.example.com/JonesFamilyHome'>
|
|
<edit xmlns='jabber:iq:joap'>
|
|
<newAddress>Building@trainset.example.com/SmithFamilyHome</newAddress>
|
|
</edit>
|
|
</iq>
|
|
]]></example>
|
|
<p>Note that the instance indentifier, and thus the instance
|
|
address, of the instance has changed. The <tt>from</tt> part
|
|
of the IQ, however, contains the old address.</p>
|
|
</section3>
|
|
</section2>
|
|
<section2 topic='<delete>'>
|
|
<p>The <delete> verb is used to delete an instance. The IQ
|
|
is of type "set". The <delete> stanza has no
|
|
sub-elements.</p>
|
|
<p>Only instances can be deleted. Classes and object servers
|
|
cannot be deleted. After an instance is deleted, it is no
|
|
longer addressable.</p>
|
|
<p>A given user may not be able to delete a particular
|
|
instance.</p>
|
|
<section3 topic='Error Codes'>
|
|
<p>The following error codes may be generated in response to a
|
|
<delete> verb.</p>
|
|
<ul>
|
|
<li><strong>404 (Not Found)</strong>: The instance to be
|
|
deleted does not exists.</li>
|
|
<li><strong>403 (Forbidden)</strong>: The user is not
|
|
authorized to delete this instance.</li>
|
|
<li><strong>405 (Not Allowed)</strong>: The client sent a
|
|
<delete> verb to an object server or class.</li>
|
|
</ul>
|
|
</section3>
|
|
<section3 topic='Examples'>
|
|
<p>To delete an instance, a client would send the following
|
|
stanza:</p>
|
|
<example caption='Deleting an Instance'><![CDATA[
|
|
<iq type='set'
|
|
id='joap_delete_1'
|
|
from='Client@example.com'
|
|
to='Building@trainset.example.com/Courthouse'>
|
|
<delete xmlns='jabber:iq:joap' />
|
|
</iq>]]></example>
|
|
<p>The instance would return this stanza:</p>
|
|
<example caption='A Deleted Instance'><![CDATA[
|
|
<iq type='result'
|
|
id='joap_delete_1'
|
|
to='Client@example.com'
|
|
from='Building@trainset.example.com/Courthouse'>
|
|
<delete xmlns='jabber:iq:joap' />
|
|
</iq>]]></example>
|
|
<p>If the user is not authorized to delete the instance, it
|
|
would return this error:</p>
|
|
<example caption='Error on Unauthorized Deletion'><![CDATA[
|
|
<iq type='error'
|
|
id='joap_delete_1'
|
|
to='Client@example.com'
|
|
from='Building@trainset.example.com/Courthouse'>
|
|
<delete xmlns='jabber:iq:joap' />
|
|
<error code='403'>
|
|
You are not authorized to delete this instance.
|
|
</error>
|
|
</iq>]]></example>
|
|
</section3>
|
|
</section2>
|
|
<section2 topic='<search>'>
|
|
<p>The <search> verb allows rudimentary searching and
|
|
listing of instances in a class. The IQ is of type
|
|
"get".</p>
|
|
<p>The client sends a <search> verb to the class,
|
|
specifying the attributes that are search criteria and values
|
|
to search for. The class returns a list of the addresses of
|
|
matching instances.</p>
|
|
<p>Multiple attributes are logically AND'd; that
|
|
is, resulting instances must match <em>all</em> of the
|
|
attribute values.</p>
|
|
<section3 topic='Value Matching'>
|
|
<p>How attribute values are specified for matching depends on
|
|
the type of the attribute.</p>
|
|
<ul>
|
|
<li>For numeric types (<int>, <double>),
|
|
<boolean>, and <dateTime.iso8601>, values match
|
|
if they are exactly equal.</li>
|
|
<li>For <string> types, a search value matches an
|
|
attribute value if it is a case-dependent substring of
|
|
that value. For example, "hat" will match
|
|
"hat", "that", and "real-time
|
|
chat server".</li>
|
|
<li>For the <base64> type, a search value matches
|
|
an attribute value if the base64-decoded value of the
|
|
search value is an 8-bit clean substring of the
|
|
base64-decoded attribute value. For example,
|
|
"aGF0Cg==" ("hat") will match
|
|
"cmVhbC10aW1lIGNoYXQK" ("real-time
|
|
chat").</li>
|
|
<li>For instance addresses, a search value matches an
|
|
attribute value if they are exactly equal.</li>
|
|
<li>For <struct> types, a search value matches an
|
|
attribute value if each of its named members matches the
|
|
corresponding named members in the attribute value, and
|
|
has the same type.</li>
|
|
<li>For <array> types, a search value matches an
|
|
attribute value if each of its members matches the
|
|
corresponding members in the attribute value, in order,
|
|
and has the same type.</li>
|
|
</ul>
|
|
</section3>
|
|
<section3 topic='Instances of Subclasses'>
|
|
<p>Classes should return all instances of the class that are
|
|
on the same object server (that is, which have the same
|
|
domain identifier in their address) and that match the search
|
|
criteria. This includes instances of subclasses of the
|
|
class.</p>
|
|
<p>Whether a class returns instances of subclasses that reside
|
|
on other object servers is implementation-dependent.
|
|
<note>This caveat is to allow different types of subclassing
|
|
policies. Classes that define a well-known, standard
|
|
interface -- for example, a class defined by a standards
|
|
organization -- would probably not be "aware" of
|
|
all instances of that class. However, it is conceivable to
|
|
have a multi-tier business application where the object
|
|
servers did know about other servers, their classes, and
|
|
their instances.</note></p>
|
|
<p>Classes cannot be searched on attributes that are defined
|
|
only in subclasses; for example, a search for the attribute
|
|
"contents" sent to the
|
|
<tt>Car@trainset.example.com</tt> class should result in a
|
|
<tt>406 (Not Acceptable)</tt> error.</p>
|
|
</section3>
|
|
<section3 topic='Empty <search>'>
|
|
<p>The semantics of an empty <search> verb is to request
|
|
<em>all</em> instances of a class. This provides a listing
|
|
or browsing functionality.</p>
|
|
</section3>
|
|
<section3 topic='Error Codes'>
|
|
<p>The following error codes may be generated in response to a
|
|
<search> verb.</p>
|
|
<ul>
|
|
<li><strong>404 (Not Found)</strong>: The class to be
|
|
searched does not exists.</li>
|
|
<li><strong>403 (Forbidden)</strong>: The user is not
|
|
authorized to search this class.</li>
|
|
<li><strong>405 (Not Allowed)</strong>: The client sent a
|
|
<search> verb to an object server or instance.</li>
|
|
<li><strong>406 (Not Acceptable)</strong>: The client sent
|
|
an <search> verb containing attributes that are not
|
|
defined for the class, or with attribute values that are
|
|
of the wrong type.</li>
|
|
</ul>
|
|
</section3>
|
|
<section3 topic='Examples'>
|
|
<p>To search for Boxcar instances carrying coal, the client
|
|
would send the following stanza to the Boxcar class:</p>
|
|
<example caption='Searching for Instances'><![CDATA[
|
|
<iq type='get'
|
|
id='joap_search_1'
|
|
from='Client@example.com'
|
|
to='Boxcar@trainset.example.com'>
|
|
<search xmlns='jabber:iq:joap'>
|
|
<attribute>
|
|
<name>contents</name>
|
|
<value><string>coal</string></value>
|
|
</attribute>
|
|
</search>
|
|
</iq>]]></example>
|
|
<p>The Boxcar class would return a list of all matching
|
|
instances:</p>
|
|
<example caption='Search Results'><![CDATA[
|
|
<iq type='result'
|
|
id='joap_search_1'
|
|
from='Boxcar@trainset.example.com'
|
|
to='Client@example.com'>
|
|
<search xmlns='jabber:iq:joap'>
|
|
<item>Boxcar@trainset.example.com/195</item>
|
|
<item>Boxcar@trainset.example.com/35</item>
|
|
<item>Boxcar@trainset.example.com/681</item>
|
|
</search>
|
|
</iq>]]></example>
|
|
<p>To get a list of all Building instances, the client would
|
|
send an empty <search> verb, as follows:</p>
|
|
<example caption='Listing All Instances of a Class'><![CDATA[
|
|
<iq type='get'
|
|
id='joap_search_2'
|
|
from='Client@example.com'
|
|
to='Building@trainset.example.com'>
|
|
<search xmlns='jabber:iq:joap' />
|
|
</iq>]]></example>
|
|
<p>The Building class would return the following stanza:</p>
|
|
<example caption='List Results'><![CDATA[
|
|
<iq type='result'
|
|
id='joap_search_2'
|
|
from='Building@trainset.example.com'
|
|
to='Client@example.com'>
|
|
<search xmlns='jabber:iq:joap'>
|
|
<item>Building@trainset.example.com/Courthouse</item>
|
|
<item>Station@trainset.example.com/Paddington</item>
|
|
<item>Station@trainset.example.com/GareDeLyon</item>
|
|
<item>Building@trainset.example.com/SmithFamilyHome</item>
|
|
</search>
|
|
</iq>]]></example>
|
|
<p>Note that the class returns instances of subclasses, as
|
|
well as direct instances of the class.</p>
|
|
</section3>
|
|
</section2>
|
|
<section2 topic='Method Calls'>
|
|
<p>Method calls in JOAP are simply XML-RPC calls, as defined in
|
|
XEP-0009.<note>XEP-0009 leaves some open questions as to use
|
|
of widely-defined extensions to the XML-RPC standard, such as
|
|
the <nil> type.</note> To call a method
|
|
on an object, the client simply sends an XML-RPC message to that
|
|
object. Method calls must match the parameters as defined in
|
|
the method definition returned by the <describe>
|
|
verb.</p>
|
|
<p>Method names must be the exact method name as returned by
|
|
<describe>. No class or instance identifier prefix (with
|
|
"." or ":") is used.</p>
|
|
<p>Note, also, that the addressee of the method call, that is,
|
|
the object that defines the method, is not specified as a
|
|
parameter of the method, as it is in some programming
|
|
languages. The addressee of the method is implicit in the
|
|
address to which the method was sent.</p>
|
|
<section3 topic='Examples'>
|
|
<p>To start the event log on the train set server, the client
|
|
would send the following stanza:</p>
|
|
<example caption='Method Call on an Object Server'><![CDATA[
|
|
<iq type='set'
|
|
id='joap_xmlrpc_1'
|
|
from='Client@example.com'
|
|
to='trainset.example.com'>
|
|
<query xmlns='jabber:iq:rpc'>
|
|
<methodCall>
|
|
<methodName>startLogging</methodName>
|
|
</methodCall>
|
|
</query>
|
|
</iq>]]></example>
|
|
<p>The object server would respond with the following results:</p>
|
|
<example caption='Method Call on an Object Server'><![CDATA[
|
|
<iq type='result'
|
|
id='joap_xmlrpc_1'
|
|
to='Client@example.com'
|
|
from='trainset.example.com'>
|
|
<query xmlns='jabber:iq:rpc'>
|
|
<methodResponse>
|
|
<params>
|
|
<param>
|
|
<value><boolean>1</boolean></value>
|
|
</param>
|
|
</params>
|
|
</methodResponse>
|
|
</query>
|
|
</iq>]]></example>
|
|
<p>To retrieve the next available Car tracking number, the
|
|
client would send the following stanza to the Car class:</p>
|
|
<example caption='Method Call on a Class'><![CDATA[
|
|
<iq type='set'
|
|
id='joap_xmlrpc_2'
|
|
from='Client@example.com'
|
|
to='Car@trainset.example.com'>
|
|
<query xmlns='jabber:iq:rpc'>
|
|
<methodCall>
|
|
<methodName>nextTrackingNumber</methodName>
|
|
</methodCall>
|
|
</query>
|
|
</iq>]]></example>
|
|
<p>The class would respond with the following results:</p>
|
|
<example caption='Results of a Class Method Call'><![CDATA[
|
|
<iq type='result'
|
|
id='joap_xmlrpc_2'
|
|
to='Client@example.com'
|
|
from='Car@trainset.example.com'>
|
|
<query xmlns='jabber:iq:rpc'>
|
|
<methodResponse>
|
|
<params>
|
|
<param>
|
|
<value><i4>909</i4></value>
|
|
</param>
|
|
</params>
|
|
</methodResponse>
|
|
</query>
|
|
</iq>]]></example>
|
|
<p>To make a Switch change to a different track segment, the
|
|
client would send the following stanza to the instance:</p>
|
|
<example caption='Method Call on an Instance'><![CDATA[
|
|
<iq type='set'
|
|
id='joap_xmlrpc_3'
|
|
from='Client@example.com'
|
|
to='Switch@trainset.example.com/981'>
|
|
<query xmlns='jabber:iq:rpc'>
|
|
<methodCall>
|
|
<methodName>switchTo</methodName>
|
|
<params>
|
|
<param>
|
|
<value>TrackSegment@trainset.example.com/119</value>
|
|
</param>
|
|
</params>
|
|
</methodCall>
|
|
</query>
|
|
</iq>]]></example>
|
|
<p>The instance would respond with the following results:</p>
|
|
<example caption='Results of an Instance Method Call'><![CDATA[
|
|
<iq type='result'
|
|
id='joap_xmlrpc_3'
|
|
from='Switch@trainset.example.com/981'
|
|
to='Client@example.com'>
|
|
<query xmlns='jabber:iq:rpc'>
|
|
<methodResponse>
|
|
<params>
|
|
<param>
|
|
<value><boolean>1</boolean></value>
|
|
</param>
|
|
</params>
|
|
</methodResponse>
|
|
</query>
|
|
</iq>]]></example>
|
|
</section3>
|
|
</section2>
|
|
</section1>
|
|
<section1 topic='Potential Applications'>
|
|
<section2 topic='Application Server'>
|
|
<p>A simple application server can be provided using JOAP. This is merely
|
|
the degenerate case of an object server that provides only methods and
|
|
attributes, with no classes.</p>
|
|
</section2>
|
|
<section2 topic='Relational Database Interface'>
|
|
<p>A more complex example would be an interface to a relational database
|
|
server, such as Oracle, PostgreSQL, or mySQL. The object server would
|
|
represent a single database within the database server. Each table in
|
|
the database would be represented by a class with no class attributes
|
|
or methods. Each row in the database would be an instance of its
|
|
table's class, with attributes but no methods.</p>
|
|
</section2>
|
|
<section2 topic='N-Tier Application'>
|
|
<p>A distributed n-tier application can be built fairly directly
|
|
with JOAP. N-tier applications are usually defined as having
|
|
three main segments:</p>
|
|
<ul>
|
|
<li>A user-interface segment</li>
|
|
<li>A business-object segment, defining objects with business
|
|
rules encoded into their behavior</li>
|
|
<li>A data-storage segment, handling basic storage of
|
|
relatively unintelligent objects</li>
|
|
</ul>
|
|
<p>With JOAP, application developers can create the last two
|
|
segments with a JOAP interface. User-interface clients can use
|
|
JOAP to access and manipulate the business objects in a
|
|
business object server. In turn, the business objects can use
|
|
JOAP to manipulate underlying database objects in the data
|
|
storage layer (perhaps implemented using a relational database
|
|
interface, as defined above).</p>
|
|
</section2>
|
|
<section2 topic='Jabber Component Controller'>
|
|
<p>Jabber protocols typically define a base set of functionality
|
|
for a component to provide. Implementers often want to provide
|
|
specialized, fine-grained control of the component that is not
|
|
part of the core functionality of a component. For example,
|
|
the implementer may wish to allow administrators to get
|
|
metrics on a component, enable or review logs, note error
|
|
situations, or configure the component remotely.<note>Most
|
|
Jabber components currently define Web interfaces, or
|
|
command-line scripts, to perform this kind of
|
|
control.</note></p>
|
|
<p>A component can provide an additional JOAP interface, along
|
|
with its regular protocol-specific interface, to enable this
|
|
kind of control functionality. Implementers can in this way
|
|
provide implementation-specific functionality in an open
|
|
way.</p>
|
|
<p>For example, if <tt>conference.example.com</tt> is
|
|
a MUC component, <tt>control.conference.example.com</tt> might
|
|
be a JOAP component with access to the internal data
|
|
structures of the MUC component. A conference room addressed
|
|
in the MUC component as
|
|
<tt>ModelTrains@conference.example.com</tt> might be addressed
|
|
in the JOAP component as
|
|
<tt>Room@control.conference.example.com/ModelTrains</tt>.</p>
|
|
</section2>
|
|
<section2 topic='Distributed Object System Gateway'>
|
|
<p>There are a number of existing distributed object systems,
|
|
such as SOAP, CORBA, distributed OLE, Enterprise Java Beans,
|
|
etc.</p>
|
|
<p>It would be reasonable to create gateways for these object
|
|
systems or object servers implementing their protocols using
|
|
JOAP. JOAP could also be used to allow disparate object
|
|
systems to communicate through a common protocol.</p>
|
|
</section2>
|
|
</section1>
|
|
<section1 topic='Implementation Notes'>
|
|
<p>To follow.</p>
|
|
</section1>
|
|
<section1 topic='Security Considerations'>
|
|
<p>This section describes some security considerations for
|
|
implementers of JOAP.</p>
|
|
<section2 topic='Authentication'>
|
|
<p>No provision is made for authentication of users to the
|
|
object server. Jabber users authenticate to a login server
|
|
before they are able to send any Jabber stanzas.</p>
|
|
</section2>
|
|
<section2 topic='Authorization'>
|
|
<p>Authorization for users to access and manipulate objects and
|
|
attributes in JOAP is fine-grained; object servers can return
|
|
error codes to indicate a lack of authorization for any given
|
|
attribute, object, or method.</p>
|
|
<p>No provision is made to define a user's authorization for an
|
|
object, attribute, or method. Implicit authorization is
|
|
outlined with the results of the <describe> verb.</p>
|
|
<ul>
|
|
<li>For attributes, if a user is unauthorized to <read> the
|
|
attribute, the object server should not return a definition of
|
|
the attribute in the <describe> results.</li>
|
|
<li>If a user is unauthorized to <edit> an attribute, the
|
|
object server should note that the the attribute is not
|
|
writable in the <describe> results.</li>
|
|
<li>If a user is unauthorized to execute a method, the object
|
|
server should not return a definition of the attribute in
|
|
the <describe> results.</li>
|
|
<li>For classes that the user is not allowed to access at all,
|
|
the object server should not return a reference to that
|
|
class in the <describe> results for the object
|
|
server.</li>
|
|
<li>For instances that the user is not allowed to access at
|
|
all, the object server should not return references to that
|
|
instance in <search> results.</li>
|
|
</ul>
|
|
</section2>
|
|
<section2 topic='Privacy and Confidentiality'>
|
|
<p>No provision is made in the JOAP protocol for providing
|
|
privacy and confidentiality in JOAP conversations. This is
|
|
left up to existing, more general Jabber protocols and
|
|
extensions.</p>
|
|
<p>Confidentiality from external, non-Jabber observers can be
|
|
obtained using transport-layer security (TLS) in all legs of
|
|
the Jabber path -- from client to server to (potentially)
|
|
another server to the object server component.</p>
|
|
<p>Maintaining confidentiality against observers in the Jabber
|
|
pathway -- for example, servers relaying JOAP stanzas --
|
|
requires using end-to-end encryption.</p>
|
|
<p>Due to the nature of the JOAP addressing scheme, however,
|
|
perfect confidentiality cannot be preserved. Even if the
|
|
contents of an IQ packet are encrypted, the address of the
|
|
object the packet is sent to -- e.g.,
|
|
<tt>Tips@whistleblower.example.org/NuclearRegulatoryInfractions</tt>
|
|
-- will reveal some information about the JOAP
|
|
conversation which could be harmful to the user.</p>
|
|
</section2>
|
|
</section1>
|
|
<section1 topic='IANA Considerations'>
|
|
<p>This document requires no interaction with the IANA.</p>
|
|
</section1>
|
|
<section1 topic='XMPP Registrar Considerations'>
|
|
<p>This protocol defines one new namespace, 'jabber:iq:joap'.</p>
|
|
<p>Experimental implementations of this protocol should use the
|
|
namespace '<tt>http://www.xmpp.org/extensions/xep-0075.html#0.3</tt>' to
|
|
avoid conflicts with future versions.</p>
|
|
</section1>
|
|
<section1 topic='Future Considerations'>
|
|
<ul>
|
|
<li>The presence mechanism provided by Jabber is currently not
|
|
integrated into the JOAP protocol. It would be relatively
|
|
easy to incorporate an observation mechanism, based on
|
|
presence, that would enable JOAP clients to request state
|
|
updates on JOAP instances. It is currently an open question
|
|
as to whether this would be genuinely useful, or merely a
|
|
"gee-whiz" add-on that needlessly complicates
|
|
implementation of the JOAP protocol.</li>
|
|
<li>More sophisticated distributed object protocol mechanisms,
|
|
such as transactions, are not addressed in this
|
|
specification.</li>
|
|
<li>The JOAP addressing mechanism restricts the type of Jabber
|
|
entity that can act as an object server. A Jabber instant
|
|
messaging client, for example, is normally addressed with
|
|
username and resource, such as
|
|
'AJabberUser@example.com/Home'. This address has no place
|
|
to hang the class and instance identifiers to allow
|
|
JOAP interactions.</li>
|
|
<li>Additionally, the JOAP addressing mechanism inhibits
|
|
letting components that already use the node and resource
|
|
identifier parts of their addresses, such as multi-user
|
|
chat (MUC) services. This restriction can be worked around by
|
|
providing corresponding JOAP components for existing Jabber
|
|
components.</li>
|
|
<li>An additional type for object references may be called
|
|
for.</li>
|
|
<li>The addition of the widely used <nil> XML-RPC data
|
|
type may be called for.</li>
|
|
<li>Searching is fairly rudimentary; a full boolean logic (and,
|
|
or, not) may be necessary to provide rich searching.</li>
|
|
<li>There is no indication in class descriptions of the
|
|
inheritance hierarchy of the class, or which superclass's
|
|
implementation of a method the class may use. This is an
|
|
implementation decision, and it seems counterproductive to
|
|
force any given inheritance method on the implementer.</li>
|
|
<li>Some functionality will be expensive using JOAP. An example
|
|
might be finding all Cars in a Train and adding them to
|
|
another Train. In our example, this would require one IQ to
|
|
get the train's cars, and N many other IQs to update each
|
|
Car. A batching mechanism -- being able to send multiple
|
|
updates in one IQ message -- would make this somewhat less
|
|
chatty. However, this functionality may be better addressed by
|
|
a global Jabber batching mechanism, rather than
|
|
special-purpose batching just for JOAP.</li>
|
|
<li>A more appropriate term than <verb> may be necessary
|
|
to describe the different types of IQs that make up the JOAP
|
|
namespace.</li>
|
|
<li>The names of the verbs come from the so-called basic READ
|
|
data-manipulation functions: read, edit, add, delete. A more
|
|
SQL-oriented set of names might be SELECT, UPDATE, INSERT,
|
|
DELETE. A set of names from C-related object languages would
|
|
be get, set, new, destroy or delete.</li>
|
|
<li>No mechanism is provided to describe the range of an
|
|
attribute. For example, if an attribute can only be an integer
|
|
less than 10, or a string in the set {'open', 'closed'}, there
|
|
is no allowance for describing this in JOAP.</li>
|
|
<li>Currently, <tt>struct</tt> and <tt>array</tt> attributes and
|
|
parameters are described just with the "struct" and
|
|
"array" types, and no definition is given of their
|
|
parts' types, names, or semantics. It may be valuable to
|
|
expand JOAP type descriptions to also describe the members of
|
|
a <tt>struct</tt> or <tt>array</tt>.</li>
|
|
</ul>
|
|
</section1>
|
|
<section1 topic='Appendix A: Glossary'>
|
|
<p>The following glossary collects some definitions of terms used
|
|
in this document.</p>
|
|
<dl>
|
|
<di><dt>Object services</dt><dd>Modelling an object or
|
|
collection of objects, and providing an interface to
|
|
manipulate those objects to other entities.</dd></di>
|
|
<di><dt>Object server</dt><dd>A Jabber component that
|
|
provides object services.</dd></di>
|
|
<di><dt>Class</dt><dd>A category of object
|
|
instances that defines their structure and interface.</dd></di>
|
|
<di><dt>Instance</dt><dd>A collection of
|
|
data with identity (address), state (attributes), and
|
|
behavior (methods).</dd></di>
|
|
<di><dt>Attribute</dt><dd>A unit of state that makes up
|
|
part of an object server, instance, or class.</dd></di>
|
|
<di><dt>Method</dt><dd>A unit of behavior.</dd></di>
|
|
<di><dt>Object</dt><dd>An object server, class, or
|
|
instance.</dd></di>
|
|
<di><dt>User</dt><dd>A person or process that accesses
|
|
object services through JOAP.</dd></di>
|
|
<di><dt>Client</dt><dd>The software or agent a user
|
|
employs to access object services through JOAP.</dd></di>
|
|
<di><dt>Instance address</dt><dd>The full JID of an
|
|
instance, e.g.,
|
|
<tt>Train@trainset.example.com/OrangeBlossomSpecial</tt>.</dd></di>
|
|
<di><dt>Instance identifier</dt><dd>The resource
|
|
identifier part of an instance address. For example, in
|
|
<tt>Train@trainset.example.com/OrangeBlossomSpecial</tt>, the
|
|
instance identifier is <tt>OrangeBlossomSpecial</tt>.</dd></di>
|
|
<di><dt>Class address</dt><dd>The full JID of a class,
|
|
e.g., <tt>Switch@trainset.example.com</tt>.</dd></di>
|
|
<di><dt>Class identifier</dt><dd>The node identifier part
|
|
of a class address. For example, in
|
|
<tt>Switch@trainset.example.com</tt>, the class identifier is
|
|
<tt>Switch</tt></dd></di>
|
|
<di><dt>Authentication</dt><dd>The act of determining
|
|
that a user is who they say they are. In the Jabber world, this
|
|
is done at login time.</dd></di>
|
|
<di><dt>Authorization</dt><dd>The act of determining
|
|
whether a given user has the right to execute a particular
|
|
action.</dd></di>
|
|
</dl>
|
|
</section1>
|
|
<section1 topic='Appendix B: JOAP XML Schema'>
|
|
<p>The following is an XML Schema for JOAP.</p>
|
|
<code><![CDATA[
|
|
<?xml version='1.0' encoding='UTF-8'?>
|
|
<schema xmlns='http://www.w3.org/2001/XMLSchema'
|
|
xmlns:joap='jabber:iq:joap'
|
|
targetNamespace='jabber:iq:joap'
|
|
elementFormDefault='qualified'
|
|
attributeFormDefault='unqualified'>
|
|
<element name='describe'>
|
|
<complexType>
|
|
<choice>
|
|
<group ref='joap:DescribeRequest' />
|
|
<group ref='joap:DescribeResponse' />
|
|
</choice>
|
|
</complexType>
|
|
</element>
|
|
<element name='read'>
|
|
<complexType>
|
|
<choice>
|
|
<group ref='joap:ReadRequest' />
|
|
<group ref='joap:ReadResponse' />
|
|
</choice>
|
|
</complexType>
|
|
</element>
|
|
<element name='edit'>
|
|
<complexType>
|
|
<choice>
|
|
<group ref='joap:EditRequest' />
|
|
<group ref='joap:EditResponse' />
|
|
</choice>
|
|
</complexType>
|
|
</element>
|
|
<element name='add'>
|
|
<complexType>
|
|
<choice>
|
|
<group ref='joap:AddRequest' />
|
|
<group ref='joap:AddResponse' />
|
|
</choice>
|
|
</complexType>
|
|
</element>
|
|
<element name='delete'>
|
|
<complexType>
|
|
<choice>
|
|
<group ref='joap:DeleteRequest' />
|
|
<group ref='joap:DeleteResponse' />
|
|
</choice>
|
|
</complexType>
|
|
</element>
|
|
<element name='search'>
|
|
<complexType>
|
|
<choice>
|
|
<group ref='joap:SearchRequest' />
|
|
<group ref='joap:SearchResponse' />
|
|
</choice>
|
|
</complexType>
|
|
</element>
|
|
<group name='DescribeRequest'>
|
|
<sequence /> <!-- empty -->
|
|
</group>
|
|
<group name='DescribeResponse'>
|
|
<sequence>
|
|
<element name='desc' type='joap:Description'
|
|
minOccurs='0' maxOccurs='unbounded' />
|
|
<element name='attributeDescription' type='joap:AttributeDescription'
|
|
minOccurs='0' maxOccurs='unbounded' />
|
|
<element name='methodDescription' type='joap:MethodDescription'
|
|
minOccurs='0' maxOccurs='unbounded' />
|
|
<choice>
|
|
<element name='superclass' type='joap:ClassAddress'
|
|
minOccurs='0' maxOccurs='unbounded' />
|
|
<element name='class' type='joap:ClassAddress'
|
|
minOccurs='0' maxOccurs='unbounded' />
|
|
</choice>
|
|
<element name='timestamp' type='joap:Timestamp'
|
|
minOccurs='0' maxOccurs='1' />
|
|
</sequence>
|
|
</group>
|
|
<group name='ReadRequest'>
|
|
<sequence>
|
|
<element name='name' type='joap:JOAPName'
|
|
minOccurs='0' maxOccurs='unbounded' />
|
|
</sequence>
|
|
</group>
|
|
<group name='ReadResponse'>
|
|
<sequence>
|
|
<element name='attribute' type='joap:Attribute'
|
|
minOccurs='0' maxOccurs='unbounded' />
|
|
<element name='timestamp' type='joap:Timestamp'
|
|
minOccurs='0' maxOccurs='1' />
|
|
</sequence>
|
|
</group>
|
|
<group name='EditRequest'>
|
|
<sequence>
|
|
<element name='attribute' type='joap:Attribute'
|
|
minOccurs='0' maxOccurs='unbounded' />
|
|
</sequence>
|
|
</group>
|
|
<group name='EditResponse'>
|
|
<sequence>
|
|
<element name='newAddress' type='joap:InstanceAddress'
|
|
minOccurs='0' maxOccurs='1' />
|
|
</sequence>
|
|
</group>
|
|
<group name='AddRequest'>
|
|
<sequence>
|
|
<element name='attribute' type='joap:Attribute'
|
|
minOccurs='0' maxOccurs='unbounded' />
|
|
</sequence>
|
|
</group>
|
|
<group name='AddResponse'>
|
|
<sequence>
|
|
<element name='newAddress' type='joap:InstanceAddress'
|
|
minOccurs='1' maxOccurs='1' />
|
|
</sequence>
|
|
</group>
|
|
<group name='DeleteRequest'>
|
|
<sequence /> <!-- empty -->
|
|
</group>
|
|
<group name='DeleteResponse'>
|
|
<sequence /> <!-- empty -->
|
|
</group>
|
|
<group name='SearchRequest'>
|
|
<sequence>
|
|
<element name='attribute' type='joap:Attribute'
|
|
minOccurs='0' maxOccurs='unbounded' />
|
|
</sequence>
|
|
</group>
|
|
<group name='SearchResponse'>
|
|
<sequence>
|
|
<element name='item' type='joap:InstanceAddress'
|
|
minOccurs='0' maxOccurs='unbounded' />
|
|
</sequence>
|
|
</group>
|
|
<complexType name='Attribute'>
|
|
<sequence>
|
|
<element name='name' type='joap:JOAPName'
|
|
minOccurs='1' maxOccurs='1' />
|
|
<element name='value' type='joap:JOAPValue'
|
|
minOccurs='1' maxOccurs='1' />
|
|
</sequence>
|
|
</complexType>
|
|
<complexType name='AttributeDescription'>
|
|
<!-- XXX: enforce name rules -->
|
|
<sequence>
|
|
<element name='name' type='joap:JOAPName'
|
|
minOccurs='1' maxOccurs='1' />
|
|
<element name='type' type='joap:JOAPType'
|
|
minOccurs='1' maxOccurs='1' />
|
|
<element name='desc' type='joap:Description'
|
|
minOccurs='0' maxOccurs='unbounded' />
|
|
</sequence>
|
|
<attribute name='required' type='boolean' default='false' />
|
|
<attribute name='writable' type='boolean' default='false' />
|
|
<attribute name='allocation' type='joap:Allocation' />
|
|
</complexType>
|
|
<complexType name='MethodDescription'>
|
|
<sequence>
|
|
<element name='name' type='joap:JOAPName'
|
|
minOccurs='1' maxOccurs='1' />
|
|
<element name='returnType' type='joap:JOAPType'
|
|
minOccurs='1' maxOccurs='1'/>
|
|
<element name='params' minOccurs='0' maxOccurs='1'>
|
|
<complexType>
|
|
<sequence>
|
|
<element name='param' minOccurs='0' maxOccurs='unbounded' >
|
|
<complexType>
|
|
<sequence>
|
|
<element name='name' type='joap:JOAPName'
|
|
minOccurs='1' maxOccurs='1' />
|
|
<element name='type' type='joap:JOAPType'
|
|
minOccurs='1' maxOccurs='1' />
|
|
<element name='desc' type='joap:Description'
|
|
minOccurs='0' maxOccurs='unbounded' />
|
|
</sequence>
|
|
</complexType>
|
|
</element>
|
|
</sequence>
|
|
</complexType>
|
|
</element>
|
|
<element name='desc' type='joap:Description'
|
|
minOccurs='0' maxOccurs='unbounded' />
|
|
</sequence>
|
|
<attribute name='allocation' type='joap:Allocation' />
|
|
</complexType>
|
|
<simpleType name='ClassAddress'>
|
|
<restriction base='string'>
|
|
<pattern value='[^@]+@[a-zA-Z0-9\.]+' />
|
|
</restriction>
|
|
</simpleType>
|
|
<simpleType name='InstanceAddress'>
|
|
<restriction base='string'>
|
|
<pattern value='[^@]+@[a-zA-Z0-9\.]+/.+' />
|
|
</restriction>
|
|
</simpleType>
|
|
<simpleType name='XMLRPCType'>
|
|
<restriction base='string'>
|
|
<enumeration value='int' />
|
|
<enumeration value='i4' />
|
|
<enumeration value='double' />
|
|
<enumeration value='boolean' />
|
|
<enumeration value='string' />
|
|
<enumeration value='array' />
|
|
<enumeration value='struct' />
|
|
</restriction>
|
|
</simpleType>
|
|
<simpleType name='JOAPType'>
|
|
<union memberTypes='ClassAddress XMLRPCType' />
|
|
</simpleType>
|
|
<simpleType name='JOAPName'>
|
|
<restriction base='string'>
|
|
<pattern value='[a-zA-Z_][0-9a-zA-Z_]*'/>
|
|
</restriction>
|
|
</simpleType>
|
|
<simpleType name='Boolean'>
|
|
<restriction base='unsignedByte'>
|
|
<enumeration value='0' />
|
|
<enumeration value='1' />
|
|
</restriction>
|
|
</simpleType>
|
|
<!-- FIXME: figure out how to do this without using mixed
|
|
content, which allows stuff we don't want. -->
|
|
<complexType name='JOAPValue' mixed='true'>
|
|
<choice minOccurs='0'>
|
|
<element name='i4' type='integer' />
|
|
<element name='int' type='integer' />
|
|
<element name='boolean' type='joap:Boolean' />
|
|
<element name='string' type='string' />
|
|
<element name='double' type='decimal' />
|
|
<element name='datetime.iso8601' type='dateTime' />
|
|
<element name='base64' type='base64Binary' />
|
|
<element name='struct' type='joap:XMLRPCStruct' />
|
|
<element name='array' type='joap:XMLRPCArray' />
|
|
</choice>
|
|
</complexType>
|
|
<complexType name='XMLRPCStruct'>
|
|
<sequence>
|
|
<element name='member' minOccurs='1' maxOccurs='unbounded'>
|
|
<complexType>
|
|
<sequence>
|
|
<element name='name' minOccurs='1' maxOccurs='1'
|
|
type='string' />
|
|
<element name='value' minOccurs='1' maxOccurs='1'
|
|
type='joap:JOAPValue' />
|
|
</sequence>
|
|
</complexType>
|
|
</element>
|
|
</sequence>
|
|
</complexType>
|
|
<complexType name='XMLRPCArray'>
|
|
<sequence>
|
|
<element name='data' minOccurs='1' maxOccurs='1'>
|
|
<complexType>
|
|
<sequence>
|
|
<element name='value' type='joap:JOAPValue'
|
|
minOccurs='0' maxOccurs='unbounded' />
|
|
</sequence>
|
|
</complexType>
|
|
</element>
|
|
</sequence>
|
|
</complexType>
|
|
<simpleType name='Allocation'>
|
|
<restriction base='string'>
|
|
<enumeration value='instance' />
|
|
<enumeration value='class' />
|
|
</restriction>
|
|
</simpleType>
|
|
<simpleType name='Description'>
|
|
<restriction base='string' />
|
|
</simpleType>
|
|
<simpleType name='Timestamp'>
|
|
<restriction base='dateTime' />
|
|
</simpleType>
|
|
</schema>
|
|
]]>
|
|
</code>
|
|
</section1>
|
|
<section1 topic='Appendix C: JOAP DTD'>
|
|
<p>The following is a document-type description (DTD) for JOAP.</p>
|
|
<code><![CDATA[
|
|
<!ELEMENT name (#PCDATA)>
|
|
<!ELEMENT type (#PCDATA)>
|
|
<!ELEMENT desc (#PCDATA)>
|
|
<!ATTLIST desc
|
|
xml:lang NMTOKEN #IMPLIED>
|
|
<!ELEMENT i4 (#PCDATA)>
|
|
<!ELEMENT int (#PCDATA)>
|
|
<!ELEMENT string (#PCDATA)>
|
|
<!ELEMENT double (#PCDATA)>
|
|
<!ELEMENT datetime.iso8601 (#PCDATA)>
|
|
<!ELEMENT base64 (#PCDATA)>
|
|
<!ELEMENT class (#PCDATA)>
|
|
<!ELEMENT superclass (#PCDATA)>
|
|
<!ELEMENT item (#PCDATA)>
|
|
<!ELEMENT returnType (#PCDATA)>
|
|
<!ELEMENT member (name, value)>
|
|
<!ELEMENT struct (member+)>
|
|
<!ELEMENT data (value+)>
|
|
<!ELEMENT array (data)>
|
|
<!ELEMENT value (#PCDATA|i4|int|string|double|datetime.iso8601|base64|struct|array)*>
|
|
<!ELEMENT attribute (name, value)>
|
|
<!ELEMENT timestamp (#PCDATA)>
|
|
<!ELEMENT newAddress (#PCDATA)>
|
|
<!ELEMENT attributeDescription (name, type, desc*)>
|
|
<!ATTLIST attributeDescription
|
|
required (true|false|0|1) "false"
|
|
writable (true|false|0|1) "false"
|
|
allocation (class|instance) "instance">
|
|
<!ELEMENT params (param+)>
|
|
<!ELEMENT param (name, type, desc*)>
|
|
<!ELEMENT methodDescription (name, returnType, params?, desc*)>
|
|
<!ATTLIST methodDescription
|
|
allocation (class|instance) "instance">
|
|
<!ELEMENT describe (desc*, attributeDescription*, methodDescription*,
|
|
(class*|superclass*), timestamp?)>
|
|
<!ELEMENT read (name*|(attribute*, timestamp?))>
|
|
<!ELEMENT edit (attribute*|newAddress?)>
|
|
<!ELEMENT add (attribute*|newAddress)>
|
|
<!ELEMENT search (attribute*|item*)>
|
|
<!ELEMENT delete EMPTY>
|
|
]]>
|
|
</code>
|
|
</section1>
|
|
<section1 topic='Appendix D: Objects in Extended Example'>
|
|
<p>Because JOAP requires some significant examples to define the
|
|
protocol, an example domain was developed to provide
|
|
consistency. Readers familiar with UML may find the following diagram
|
|
useful to illustrate some of the fine points of JOAP listed
|
|
above.</p>
|
|
<example caption='Object Diagram'><![CDATA[
|
|
Train:
|
|
number: i4
|
|
name: string
|
|
location: TrackSegment
|
|
cars: Car[]
|
|
void forward()
|
|
void back()
|
|
void insertCar(Car car, Car before)
|
|
|
|
Car:
|
|
trackingNumber: i4
|
|
i4 nextTrackingNumber() {class}
|
|
|
|
Caboose: Car
|
|
|
|
Engine: Car
|
|
canPull: i4
|
|
|
|
Boxcar: Car
|
|
contents: string
|
|
|
|
PassengerCar: Car
|
|
passengers: i4
|
|
|
|
Building:
|
|
name: string
|
|
size: struct (length: i4, width: i4)
|
|
|
|
TrackSegment:
|
|
previous: TrackSegment
|
|
next: TrackSegment
|
|
|
|
Switch:
|
|
in: TrackSegment
|
|
out: TrackSegment[]
|
|
boolean switchTo(TrackSegment)
|
|
|
|
Station: TrackSegment, Building
|
|
]]></example>
|
|
</section1>
|
|
</xep>
|