OpenAjax Metadata Specification API Metadata
From MemberWiki
Notes:
- This wiki page holds a portion of the latest internal editorial draft for what ultimately will become the OpenAjax Metadata 1.0 Specification. The base wiki page for this (latest) version of the draft specification is at http://www.openajax.org/member/wiki/OpenAjax_Metadata_Specification.
Here is the proposed way for the IDE WG to edit this specification:
- All textual content that has normal text properties (i.e., black) and has no colored status text (e.g., does not say DRAFT CONSENSUS, TENTATIVELY APPROVED or APPROVED) represents preliminary proposed text that requires further review and discussion.
- Members of OpenAjax Alliance are encourage to place inline comments into this document, preferably by identifying your name or initials before your comment, such as "Mary: This bullet should be moved above previous bullet".
- When an item has been deemed complete by the WG chair due to committee consensus, then the annotation APPROVED will be placed at the end of an approved block of text (e.g., paragraph or bullet). Note that during the development phase of this specification, the group can change its mind and "un-approve" text that was previously approved.
- When an item has been deemed near complete by the WG chair due to committee consensus, but further review is necessary (e.g., review final wording), then the annotation DRAFT CONSENSUS or TENTATIVELY APPROVED will be placed at the end of given block of text (e.g., paragraph or bullet).
3 API Metadata
Introduction
This chapter defines the OpenAjax Metadata XML grammar for the runtime JavaScript APIs (e.g., classes and methods) that are available for a given Ajax library.
While it is possible that Ajax libraries might choose to use this XML grammar as the original source documentation for its JavaScript APIs, in a more common scenario the Ajax library will use a different format such as JSDoc for API documentation within the original JavaScript files, and then supply a converter utility that converts the inline document comments into one or more OpenAjax Metadata files:
Original JavaScript files (with doc-comments inline) => CONVERTER => OpenAjax Metadata
Replace the above with a picture
Feature overview
Proposed editorial strategy: This section would be concise and provide a bulleted list of the kinds of features that API metadata describes (e.g., classes, globals, interfaces, methods, properties, events, ...), with links to the elements that correspond to those features, and then the main body of the chapter would be the detailed reference section 2008-04-22: Draft consensus. Reasonable approach.
2008-04-29 Draft consensus: (Not sure where to put this, so putting this here for now) We decided that in IDE workflows the tool loads a set of metadata files and these files can reference the datatypes defined in other files, but for mashup workflows, each widget file is self-contained except for any dependencies that are explicitly listed by its <require> elements.
Example
Need to update this example to show some recent decisions, such as distinguishing between fields and properties.
Here is an example:
<?xml version="1.0" encoding="UTF-8"?>
<api xmlns="http://openajax.org/metadata" version="...">
<class name="libraryname.ClassName" superclass="Object">
<constructors>
<constructor>
<description>Constructor description</description>
<parameters>
<parameter name="message" usage="required" datatype="String">
<description>Parameter description</description>
</parameter>
</parameters>
<returnType datatype="Object">
<description>...</description>
</returnType>
</constructor>
</constructors>
<properties>
<property name="propertyInstance" readonly="false" scope="instance" datatype="String" default="">
<description>Property description</description>
</property>
<property name="propertyStatic" readonly="false" scope="static" datatype="String" default="">
<description>Property description</description>
</property>
</properties>
<methods>
<method name="functionInstance" scope="instance">
<description>Method description</description>
<parameters>
<parameter name="param" usage="required" datatype="String">
<description>Parameter description</description>
</parameter>
</parameters>
<returnType datatype="String">
<description>...</description>
</returnType>
</method>
<method name="functionStatic" scope="static">
<description>Method description</description>
<parameters/>
<returnType datatype="String">
<description>...</description>
</returnType>
</method>
</methods>
</class>
</api>
API metadata
Need to add a short intro
The <api> element
2008-07-08 Draft Consensus: We agreed that all elements that can be used multiple times requires a plural version of the element, and that in all cases, the plurals are optional. Therefore, you can say either
<class>...</class>
<class>...</class>
or
<classes>
<class>...</class>
<class>...</class>
</classes>.
Tools must look for either (i.e., /class or /classes/class).
api_element = element api {
api_content & api_attributes & foreign_nodes
}
api_content = (
author_element* & authors_element* & class_element* & classes_element* &
config_element* & configs_element* & enum_element* & enums_element* &
globals_element* &
interface_element* & interfaces_element* & license_element? & messagebundle_element* &
mixin_element* & mixins_element* & namespace_element* & namespaces_element* &
descriptive_elements
)
api_attributes = (
language? & spec? & version? &
getterPattern? & setterPattern? & registerCallbackPattern? & unregisterCallbackPattern?
)
JSDoc v2 allows @author on constructors, methods and properties. Shouldn't we allow it in our schema also so that JSDoc can be mapped into our format (even if few people will specify @author at such a fine level and even if tools will usually ignore this information)? Editorial note: updated schema to add authors/author to api element.
The <api> element is the root element of an API file.
The version attribute specifies the version number of the JavaScript libraries that are documented by this metadata file. (See the section titled "Version number attributes" within the "Compatibility" chapter for rules on version number attributes.) 2008-05-29: Tentatively approved
The spec attribute specifies the version number of the OpenAjax Metadata spec to which this metadata file conforms. (See the section titled "Version number attributes" within the "Compatibility" chapter for rules on version number attributes.) 2008-05-29: Tentatively approved
The language attribute specifies the programming language for which the API metadata applies. The default is "javascript", which indicates the various versions of the language whose standard is named "ECMAScript" (e.g., ECMA-262) but which is often referred to as "JavaScript". 2008-07-08: Tentatively approved. Agreed on "javascript" and that it is the default value for the attribute.
The getterPattern attribute specifies not yet written, is a substitution pattern which provides the function name for the getter function, available on <property>, <properties>, <api>, and <widget>.
The setterPattern attribute specifies not yet written, same as getterPattern, except this is for the setter..
DRAFT CONSENSUS: All of the black text above reflects draft consensus from previous discussion.
Subelements defined in this chapter
Alias elements
<alias>
alias_element = element alias {
alias_content & alias_attributes & foreign_attributes
}
alias_content = (
empty
)
alias_attributes = (
name
)
The <alias> element can be used to specify an alternate name for an object that a tool might use during content assist. Typically, the alternate name is shorter and/or more understandable that the original name.
The name attribute specifies the name of the alias.
DRAFT CONSENSUS: All of the black text above reflects draft consensus from previous discussion.
<aliases>
aliases_element = element aliases {
aliases_content & aliases_attributes & foreign_nodes
}
aliases_content = (
descriptive_elements &
alias_element*
)
aliases_attributes = (
name?
)
The <aliases> element holds zero or more <alias> child elements.
The optional name attribute is meant to allow for providing a unique name for this particular <aliases> element in case multiple <aliases> are specified.
DRAFT CONSENSUS: All of the black text above reflects draft consensus from previous discussion.
Ancestor elements
<ancestor>
ancestor_element = element ancestor {
ancestor_content & ancestor_attributes & foreign_attributes
}
ancestor_content = (
empty
)
ancestor_attributes = (
datatype
)
The <ancestor> element describes not yet written
The datatype attribute specifies either the ancestor class name or ancestor interface name. The detailed description of the datatype attribute can be found in the Datatypes chapter. However, for the <ancestor> element, the value can only be the name of a class or interface and cannot be one of the core JavaScript datatypes (such as String or Object). Needs review: is this description correct?
DRAFT CONSENSUS: All of the black text above reflects draft consensus from previous discussion.
<ancestors>
ancestors_element = element ancestors {
ancestors_content & ancestors_attributes & foreign_nodes
}
ancestors_content = (
descriptive_elements &
ancestor_element*
)
ancestors_attributes = (
name?
)
The <ancestors> element holds zero or more <ancestor> child elements.
The optional name attribute is meant to allow for providing a unique name for this particular <ancestors> element in case multiple <ancestors> are specified.
DRAFT CONSENSUS: All of the black text above reflects draft consensus from previous discussion.
Class elements
<class>
class_element = element class {
class_content & class_attributes & foreign_nodes
}
class_content = (
alias_element* & aliases_element* & ancestor_element* & ancestors_element* &
config_element* & configs_element* & constructor_element* & constructors_element* &
event_element* & events_element* & mix_element* & mixes_element* &
method_element* & methods_element* & property_element* & properties_element* &
descriptive_elements & compatibility_elements
)
class_attributes = (
name & static? & superclass? & visibility? &
getterPattern? & setterPattern? & registerCallbackPattern? & unregisterCallbackPattern?
)
The <class> element describes a JavaScript class.
The name attribute specifies the absolute object name using JavaScript dot notation for the class, such as "FooToolkit.io.httpreq" (where the Foo toolkit has a main global object called "FooToolkit", a subobject "io", with subobject "httpreq" which is set up as a JavaScript class (i.e., has an appropriate constructor function).
The static attribute is a boolean. A value of true indicates that this <class> element describes a "static class", which represents an object with a set of methods and properties that are available without requiring instantiation (such as via a new operation). Static classes typically do not have constructors. 20081118: Tentative decision: Add static attribute for singleton case..
The superclass attribute specifies not yet written.
The visibility attribute specifies not yet written and can have values "public|private|protected|internal|protected-internal".
DRAFT CONSENSUS: All of the black text above reflects draft consensus from our previous discussion.
<classes>
classes_element = element classes {
classes_content & classes_attributes & foreign_nodes
}
classes_content = (
descriptive_elements &
class_element*
)
classes_attributes = (
name? &
getterPattern? & setterPattern? & registerCallbackPattern? & unregisterCallbackPattern?
)
The <classes> element holds zero or more <class> child elements.
The optional name attribute is meant to allow for providing a unique name for this particular <classes> element in case multiple <classes> are specified.
DRAFT CONSENSUS: All of the black text above reflects draft consensus from previous discussion.
Constructor elements
<constructor>
constructor_element = element constructor {
constructor_content & constructor_attributes & foreign_nodes
}
constructor_content = (
exception_element* & exceptions_element* & parameter_element* & parameters_element* &
returnType_element* & returnTypes_element* &
descriptive_elements & compatibility_elements
# Research the above, make consistent with the spec
)
constructor_attributes = (
visibility?
)
The <constructor> element describes a constructor method. A constructor can be described by multiple<constructor> element, in which case the different <constructor> elements can be used to specify different parameter and return value alternatives.
In most usage scenarios, constructors will return an Object that is an instance of the constructor's class. However, because of the possibility that a programmer might have leveraged JavaScript's flexibility to return a different value from the constructor, it is usually necessary that the <constructor> element specifies its return type explicitly. For example, suppose you have a class MyClass with a single constructor function that returns an Object of type MyClass. The metadata might look as follows (note the presence of the <returnType> element):
<class name="MyClass">
<constructor>
<!-- not shown: constructor parameters, description, etc. -->
<returnType datatype="MyClass"/>
</constructor>
</class>
The scope attribute describes not yet written and can have values instance or static.
The visibility attribute specifies not yet written and can have values "public|private|protected|internal|protected-internal".
DRAFT CONSENSUS: All of the black text above reflects decisions from previous discussion.
<constructors>
constructors_element = element constructors {
constructors_content & constructors_attributes & foreign_nodes
}
constructors_content = (
descriptive_elements &
constructor_element*
)
constructors_attributes = (
name?
)
The <constructors> element holds zero or more <constructors> child elements.
The optional name attribute is meant to allow for providing a unique name for this particular <constructors> element in case multiple <constructors> are specified.
DRAFT CONSENSUS: All of the black text above reflects draft consensus from previous discussion.
Event elements
<event>
event_element = element event {
event_content & event_attributes & foreign_nodes
}
event_content = (
handlerFunction_element? &
descriptive_elements & compatibility_elements
)
event_attributes = (
name & registerCallbackPattern? & unregisterCallbackPattern? & visibility?
)
The <event> element describes not yet written, but meant for toolkit-specific event systems. For OAHub, use topics instead.
The name attribute specifies the name of the event.
DRAFT CONSENSUS: All of the black text above reflects draft consensus from previous discussion. 2008-08-05 DRAFT CONSENSUS: We reviewed this element again and decided to keep it, along with parameters and return type. Jon added 'name' after the phone call as this was an apparent oversight and sent email asking people to make sure this wasn't a mistake.
<events>
events_element = element events {
events_content & events_attributes & foreign_nodes
}
events_content = (
descriptive_elements &
event_element*
)
events_attributes = (
name? & registerCallbackPattern? & unregisterCallbackPattern?
)
The <events> element holds zero or more <event> child elements.
The optional name attribute is meant to allow for providing a unique name for this particular <events> element in case multiple <events> are specified.
DRAFT CONSENSUS: All of the black text above reflects draft consensus from previous discussion.
<handlerFunction>
Draft consensus 2008-11-18: WG discussed and approved the write-up about this new element.
handlerFunction_element = element handlerFunction {
handlerFunction_content & handlerFunction_attributes & foreign_nodes
}
handlerFunction_content = (
parameter_element* & parameters_element* & returnType_element* & returnTypes_element* &
descriptive_elements & compatibility_elements
)
handlerFunction_attributes = (
registerCallbackPattern? & unregisterCallbackPattern?
)
The <handlerFunction> element is an optional child element to the <event> element that can be used to describe the naming pattern for the function that registers an event handler for this event and to describe the parameters to the event handler function. For example:
<event name="locationChange">
<handlerFunction registerCallbackPattern="{{event}}Handler({{callback}})">
<parameter name="lat" datatype="Number"/>
<parameter name="long" datatype="Number"/>
</handlerFunction>
</event>
In the above example, the function to register an event handler is named locationChangeHandler that takes a single parameter, which is the callback function. The event handler function will be passed two parameters, both of which are Number values.
The registerCallbackPattern attribute specifies the naming pattern for the function that registers an event handler. Details can be found below in the section titled "Pattern attributes" within the Properties chapter.
The unregisterCallbackPattern attribute specifies the naming pattern for the function that unregisters an event handler. Details can be found below in the section titled "Pattern attributes" within the Properties chapter.
Exception elements
<exception>
exception_element = element exception {
exception_content & exception_attributes & foreign_nodes
}
exception_content = (
parameter_element* & parameters_element* & property_element* & properties_element* &
returnType_element* & returnTypes_element* &
descriptive_elements & compatibility_elements
)
exception_attributes = (
datatype?
)
The <exception> element describes not yet written
The datatype attribute not yet written, but we decided that it can be either an ECMAScript core datatype such as String or a classname
DRAFT CONSENSUS: All of the black text above reflects draft consensus from previous discussion.
<exceptions>
exceptions_element = element exceptions {
exceptions_content & exceptions_attributes & foreign_nodes
}
exceptions_content = (
descriptive_elements &
exception_element*
)
exceptions_attributes = (
name?
)
The <exceptions> element holds zero or more <exception> child elements.
The optional name attribute is meant to allow for providing a unique name for this particular <exceptions> element in case multiple <exceptions> are specified.
DRAFT CONSENSUS: All of the black text above reflects draft consensus from previous discussion.
Globals elements
<globals>
globals_element = element globals {
globals_content & globals_attributes & foreign_nodes
}
globals_content = (
property_element* & properties_element* & method_element* & methods_element*
)
globals_attributes = (
getterPattern? & setterPattern? & registerCallbackPattern? & unregisterCallbackPattern?
)
The <globals> element describes not yet written
DRAFT CONSENSUS: All of the black text above reflects draft consensus from previous discussion.
Interfaces elements
<interface>
interface_element = element interface {
interface_content & interface_attributes & foreign_nodes
}
interface_content = (
ancestor_element* & ancestors_element* & config_element* & configs_element* &
constructor_element* & constructors_element* & exception_element* & exceptions_element* &
mix_element* & mixes_element* & method_element* & methods_element* &
property_element* & properties_element* &
descriptive_elements & compatibility_elements
)
interface_attributes = (
name & superclass? & visibility? &
getterPattern? & setterPattern? & registerCallbackPattern? & unregisterCallbackPattern?
)
The <interface> element describes not yet written
The name attribute specifies the absolute object name using JavaScript dot notation for the class, such as "FooToolkit.io.httpreq" (where the Foo toolkit has a main global object called "FooToolkit", a subobject "io", with subobject "httpreq" which is set up as a JavaScript class (i.e., has an appropriate constructor function).
The superclass attribute specifies not yet written.
The visibility attribute specifies not yet written and can have values "public|private|protected|internal|protected-internal".
DRAFT CONSENSUS: All of the black text above reflects draft consensus from previous discussion.
<interfaces>
interfaces_element = element interfaces {
interfaces_content & interfaces_attributes & foreign_nodes
}
interfaces_content = (
descriptive_elements &
interface_element*
)
interfaces_attributes = (
name? &
getterPattern? & setterPattern? & registerCallbackPattern? & unregisterCallbackPattern?
)
The <interfaces> element holds zero or more <interface> child elements.
The optional name attribute is meant to allow for providing a unique name for this particular <interfaces> element in case multiple <interfaces> are specified.
DRAFT CONSENSUS: All of the black text above reflects draft consensus from previous discussion.
Method elements
<method>
method_element = element method {
method_content & method_attributes & foreign_nodes
}
method_content = (
exception_element* & exceptions_element* & parameter_element* & parameters_element* &
returnType_element* & returnTypes_element* &
descriptive_elements & compatibility_elements
# Research the above, make consistent with the spec
)
method_attributes = (
name & scope? & visibility?
)
The <method> element describes not yet written
The name attribute describes not yet written.
The scope attribute describes not yet written and can have values instance or static.
The visibility attribute specifies not yet written and can have values "public|private|protected|internal|protected-internal".
DRAFT CONSENSUS: All of the black text above reflects draft consensus from previous discussion.
<methods>
methods_element = element methods {
methods_content & methods_attributes & foreign_nodes
}
methods_content = (
descriptive_elements &
method_element*
)
methods_attributes = (
name?
)
The <methods> element holds zero or more <method> child elements.
The optional name attribute is meant to allow for providing a unique name for this particular <methods> element in case multiple <methods> are specified.
DRAFT CONSENSUS: All of the black text above reflects draft consensus from previous discussion.
Mix elements
<mix>
mix_element = element mix {
mix_content & mix_attributes & foreign_nodes
}
mix_content = (
descriptive_elements
)
mix_attributes = (
datatype & fromProperty? & toProperty? & fromScope? & toScope?
)
The <mix> element indicates that methods and properties (and other features) from another object are copied (i.e., mixed in) into this object.
The datatype attribute is a reference to the 'datatype' on the <mixin>, <interface> or <class> element whose methods and properties should be mixed into this <mixin>, <interface> or <class>. This element can be used to mix in either a set of methods and properties or (if the fromProperty attribute has a value) an individual method or property.
The fromScope attribute describes not yet written and can have values instance or static.
The toScope attribute describes not yet written and can have values instance or static.
If the fromProperty attribute has a value and is not the empty string, then only a single method or property will be mixed in. The fromProperty attribute provides the name of the property that is to be copied from the referenced <mixin>, <interface> or <class> element. 20081118: DRAFT CONSENSUS: Added fromProperty and toProperty to allow for single-property mixins.
The toProperty attribute provides the name for the mixed-in property when placed on this <mixin>, <interface> or <class>. If not specified or if it is the empty string, then the mixed-in property's name has the same name as the fromProperty.
DRAFT CONSENSUS: All of the black text above reflects draft consensus from previous discussion.
<mixes>
mixes_element = element mixes {
mixes_content & mixes_attributes & foreign_nodes
}
mixes_content = (
descriptive_elements &
mix_element*
)
mixes_attributes = (
name?
)
The <mixes> element holds zero or more <mix> child elements.
The optional name attribute is meant to allow for providing a unique name for this particular <mixes> element in case multiple <mixes> are specified.
DRAFT CONSENSUS: All of the black text above reflects draft consensus from previous discussion.
Mixin elements
<mixin>
mixin_element = element mixin {
mixin_content & mixin_attributes & foreign_nodes
}
mixin_content = (
ancestor_element* & ancestors_element* & config_element* & configs_element* &
descriptive_elements
)
mixin_attributes = (
name & scope? & visibility?
)
The <mixin> element describes not yet written, but defines a collection of methods, properties, etc. that are available to be mixed into other classes (i.e., referred to by a <mix> element)
The name attribute specifies the absolute object name using JavaScript dot notation for the mixin, such as "FooToolkit.io.http" (where the Foo toolkit has a main global object called "FooToolkit", a subobject "io", with subobject "http" which is set up as a JavaScript mixin.
The scope attribute describes not yet written and can have values instance or static.
The visibility attribute specifies not yet written and can have values "public|private|protected|internal|protected-internal".
DRAFT CONSENSUS: All of the black text above reflects draft consensus from previous discussion.
<mixins>
mixins_element = element mixins {
mixins_content & mixins_attributes & foreign_nodes
}
mixins_content = (
descriptive_elements &
mixin_element*
)
mixins_attributes = (
name?
)
The <mixins> element holds zero or more <mixin> child elements.
The optional name attribute is meant to allow for providing a unique name for this particular <mixins> element in case multiple <mixins> are specified.
DRAFT CONSENSUS: All of the black text above reflects draft consensus from previous discussion.
Namespace elements
<namespace>
namespace_element = element namespace {
namespace_content & namespace_attributes & foreign_nodes
}
namespace_content = (
descriptive_elements
)
namespace_attributes = (
name & visibility?
)
The <namespace> element can be used to describes a JavaScript object that is a base object for other JavaScript classes but which itself is not a class (i.e., there is no constructor which creates instances of this object). For example, suppose there is a class named "MyLibrary.io.xhr" where the "xhr" object has a constructor, but "MyLibrary" and "io" do not. In this case, "MyLibrary" and "MyLibrary.io" are candidates for the <namespace> element. One way to use the <namespace> element is to provide descriptive information (e.g., using the <description> element) about the base object.
The name attribute specifies the absolute object name using JavaScript dot notation for the class, such as "FooToolkit.io.httpreq" (where the Foo toolkit has a main global object called "FooToolkit", a subobject "io", with subobject "httpreq" which is set up as a JavaScript class (i.e., has an appropriate constructor function).
The visibility attribute specifies not yet written and can have values "public|private|protected|internal|protected-internal".
need to document attributes
DRAFT CONSENSUS: All of the black text above reflects draft consensus from previous discussion.
<namespaces>
namespaces_element = element namespaces {
namespaces_content & namespaces_attributes & foreign_nodes
}
namespaces_content = (
descriptive_elements &
namespace_element*
)
namespaces_attributes = (
name?
)
The <namespaces> element holds zero or more <namespace> child elements.
The optional name attribute is meant to allow for providing a unique name for this particular <namespaces> element in case multiple <namespaces> are specified.
DRAFT CONSENSUS: All of the black text above reflects draft consensus from previous discussion.
Parameter elements
<parameter>
parameter_element = element parameter {
parameter_content & parameter_attributes & foreign_nodes
}
parameter_content = (
option_element* & options_element* &
parameter_element* & parameters_element* & property_element* & properties_element* &
returnType_element* & returnTypes_element* &
descriptive_elements & compatibility_elements
# Research the above, make consistent with the spec
)
parameter_attributes = (
datatype? & name & usage? &
datatype_supplemental_attributes # FIXME: Is this correct?
)
The <parameter> element describes a parameter to a JavaScript function.
The name attribute specifies the name of the corresponding parameter within the JavaScript function definition. For example, consider the following JavaScript function:
MyClass.Init = function(parm1, parm2) { ... }
The corresponding OpenAjax Metadata for this function might look like this:
<class name="MyClass">
<method name="Init">
<parameter name="parm1" .../>
<parameter name="parm2" .../>
</method>
</class>
The datatype attribute specifies the allowed datatype(s) for the parameter. See the "Datatypes" chapter for the detailed definition of this attribute.
The usage attribute specifies whether the parameter is required or optional and whether a variable number of values may be provided (i.e., zero-or-more or one-or-more). Permissible values are:
-
required(the default value for this attribute) -
optional -
zero-or-more -
one-or-more
Earlier DRAFT CONSENSUS: All of the black text above reflects draft consensus from previous discussion.
2008-08-28DRAFT CONSENSUS: Agreement that 'usage' is an optional attribute whose default value is 'required'.
<parameters>
parameters_element = element parameters {
parameters_content & parameters_attributes & foreign_nodes
}
parameters_content = (
descriptive_elements &
parameter_element*
)
parameters_attributes = (
name?
)
The <parameters> element holds zero or more <parameter> child elements.
The optional name attribute is meant to allow for providing a unique name for this particular <parameters> element in case multiple <parameters> are specified.
DRAFT CONSENSUS: All of the black text above reflects draft consensus from previous discussion.
Return type elements
2008-09-16 DRAFT CONSENSUS: Change <returns> into <returnType> with plural element <returnTypes>
<returnType>
returnType_element = element returnType {
returnType_content & returnType_attributes & foreign_nodes
}
returnType_content = (
parameter_element* & parameters_element* & property_element* & properties_element* &
returnType_element* & returnTypes_element* &
descriptive_elements
# Research the above, make consistent with the spec
)
returnType_attributes = (
datatype & paramName? & paramValue? &
datatype_supplemental_attributes # FIXME: Is this correct?
)
The <returnType> element specifies the datatype of the value that the method returns and supplemental descriptive information about the return value.
The datatype attribute specifies the datatype for the value that the method returns. The detailed specification for the datatype attribute can be found in the Datatypes chapter of this specification. However, for the <returns> element, the datatype attribute includes one additional feature that targets factory methods, where the datatype attribute can reference one of the method's parameters. In this case, the string value of the datatype attribute must exactly match the string value of the name attribute on one of the <parameter> elements for this method. If such a match exists between the <returns> element's datatype and the <parameter> element's name, then the return value from the method is the value of that parameter, which can be either a String value (the name of the class) or a Function value (the class constructor). To illustrate, suppose you have the following method definition:
<method name="classFactory"> <parameter name="classToInstantiate" datatype="String"/> <returns datatype="classToInstantiate"/> </method>
The method definition indicates that the return value from the method is an object whose classname is passed as a String to the classFactory method. Now, let's furthermore suppose this method might be invoked at runtime by any of the following:
-
myShape = classFactory('acme.graphtools.circleClass') -
myShape = classFactory('acme.graphtools.rectClass')
In this hypothetical case, the method will return an object that is either an instance of acme.graphtools.circleClass or acme.graphtools.rectClass.
Here is the same example, except that a Function value is used to identify the class:
<method name="classFactory"> <parameter name="classToInstantiate" datatype="Function"/> <returns datatype="classToInstantiate"/> </method>
For this example, the factory method might be invoked as follows (note that the arguments are not quoted, whereas in the previous String example, the class names were in quotes):
-
myShape = classFactory(acme.graphtools.circleClass) -
myShape = classFactory(acme.graphtools.rectClass)
User agents must first look to see if the specified datatype matches one of the parameter names, and then determine if the specified datatype matches one of the ECMAScript core datatypes or the name of a JavaScript class.
The paramName and paramValue attributes are most useful for factory methods where the datatype of the return value is dependent on a parameter whose possible values consists of an enumeration. If paramName and paramValue are provided, then they indicate that when the <parameter> element whose name attribute exactly matches the value of the paramName attribute and where the value of the parameter exactly matches the paramValue attribute, then the method returns the datatype specified on this <returns> element. To illustrate, suppose you have the following method definition:
<method name="classFactory">
<parameter name="classToInstantiate" datatype="String">
<options>
<option value="rect"/>
<option value="circle"/>
</options>
</parameter>
<returns paramName="classToInstantiate" paramValue="rect" datatype="acme.graphtools.rectClass"/>
<returns paramName="classToInstantiate" paramValue="circle" datatype="acme.graphtools.circleClass"/>
</method>
and furthermore suppose at runtime this method can be invoked by either myShape = classFactory('rect'); or myShape = classFactory('circle');. The above method definition indicates that: (a) when 'rect' is passed as the parameter then the return datatype is 'acme.graphtools.rectClass', and (b) when 'circle' is passed as the parameter then the return datatype is 'acme.graphtools.circleClass'.
Note that paramName and paramValue do not require the use of an enumeration (i.e., <options> and <option> elements). These attributes can also be used on parameters whose datatype is String that do not specify a discrete list of available options.
The metadata file is incorrectly formulated (i.e., in error) for the following situations: (a) if only one of paramName and paramValue are specified; (b) when paramName does not match one of the method's parameters; and (c) when a discrete enumeration is specified and paramValue does not match one of the possible values for the parameter.
Note that attribute datatype is a required attribute in OpenAjax Metadata, whereas in some inline commenting systems such as JSDoc, the datatype might be optional.
When converting from these inline commenting systems into OpenAjax Metadata, if the datatype is not specified, a suggested approach is to set datatype to Object.
DRAFT CONSENSUS: All of the black text above reflects draft consensus from previous discussion.
<returnTypes>
returnTypes_element = element returnTypes {
returnTypes_content & returnTypes_attributes & foreign_nodes
}
returnTypes_content = (
descriptive_elements &
returnType_element*
)
returnTypes_attributes = (
name?
)
The <returnTypes> element holds zero or more <returnType> child elements.
The optional name attribute is meant to allow for providing a unique name for this particular <returnTypes> element in case multiple <returnTypes> are specified.
DRAFT CONSENSUS: All of the black text above reflects draft consensus from previous discussion.
Subelements defined in other chapters
The following short sections list the subelements of <widget> that are defined in other chapters.
<author>/<authors>
Defined in the "Descriptive elements and attributes" chapter.
<available>
Defined in the "Compatibility" chapter.
<config>/<configs>
Defined in the "Properties" chapter.
<deprecated>
Defined in the " Compatibility" chapter.
descriptive_elements
Defined in the "Descriptive elements and attributes" chapter.
<description>
Defined in the "Descriptive elements and attributes" chapter.
<enum>/<enums>
Defined in the "Datatypes" chapter.
<example>/<examples>
Defined in the "Descriptive elements and attributes" chapter.
<include>
Defined in the "Inclusion" chapter.
<license>
Defined in the "Descriptive elements and attributes" chapter.
<messagebundle>
Defined in the "Localization" chapter.
<option>/<options>
Defined in the "Datatypes" chapter.
<property>/<properties>
Defined in the "Properties" chapter.
<reference>/<references>
Defined in the "Descriptive elements and attributes" chapter.
<remarks>
Defined in the "Descriptive elements and attributes" chapter.
<title>
Defined in the "Descriptive elements and attributes" chapter.
<topic>/<topics>
Defined in the "Topics" chapter.
<useragent>/<useragents>
Defined in the " Compatibility" chapter.
EDITOR: Make sure that all 'datatype' attributes refer to datatypes chapter and make sure there is appropriate writeup on classname datatypes to talk about the use of JavaScript dot notation to identify classes.
