mirror of https://github.com/moparisthebest/xeps
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1819 lines
80 KiB
1819 lines
80 KiB
<?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/> |
|
<supersedes/> |
|
<supersededby/> |
|
<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>
|
|
|