OpenAjax Metadata 1.0 Specification Properties
From MemberWiki
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 are the IDE WG's rules for editing this specification:
- The current working text for the specification has normal text properties (i.e., black)
- Open issues that require WG discussion are highlighted with red text
- Notes to the editor about necessary minor editorial changes are highlighted with purple text
Contents |
Chapter 7: Properties
Introduction
For OpenAjax Metadata, a "property" represents a variable on an object.
The following elements in the OpenAjax Metadata language can have properties (i.e., they can have <property> element children):
- Widget Metadata elements:
- API Metadata elements:
Additionally, any element for which it is possible to have a
datatype="Object"
attribute can have <property> element children
that describe the properties on the given JavaScript object.
This chapter specifies various elements having to do with properties.
- <property> element: defines a property
- <properties> element: a group of properties
- <childProperties> element: a group of properties that are attached onto child elements
- <config> element: definition for a JavaScript object (or object literal) that can be referred to by a 'datatype' attribute
This chapter also includes a Pattern attributes section that describes the rules and processing model for the following "pattern attributes":
-
getterPattern -
setterPattern -
registerHandlerPattern -
unregisterHandlerPattern
<property>
The <property> element defines a single property on a particular object.
Schema
property_element = element property {
property_content & property_attributes & foreign_nodes
}
property_content = (
option_element* & options_element* &
parameter_element* & parameters_element* & property_element* & properties_element* &
returnType_element* & returnTypes_element* &
descriptive_elements & compatibility_elements
)
property_attributes = (
datatype? & defaultValue? & hidden? & name &
readonly? & designonly? & required? & scope? &
sharedAs? & transient? & urlparam? & visibility? &
datatype_supplemental_attributes & pattern_attributes
)
Child content
This element might contain any of the following sub-elements:
- descriptive_elements (various elements, such as <description> and <example>)
- compatibility_elements (various elements, such as <available> and <deprecated>)
- <option>, <options>
- <parameter>, <parameters>
- <property>, <properties>
- <returnType>, <returnTypes>
This element MAY contain <property> or <properties> sub-elements only when the datatype attribute has the value "Object". In this case, the <property> sub-elements provide descriptive detail about the various properties on the Object.
This element MAY contain <parameter>, <parameters>, <returnTypes> or <returnTypes> sub-elements only when the datatype attribute has the value "Function". In this case, the <parameter> and <returnType> sub-elements provide descriptive detail about the parameters and return types for the Function.
If the <property> element is a descendant of a
<topic>
element, then the
<property> element or any descendant element
MUST NOT be "Function" because the message payload described by the
<topic>
element MUST be a
JSON-serializable data value.
Attribute summary
| Attribute | Description | Type | Required | Default |
|---|---|---|---|---|
| datatype | Allowed datatypes for this property | String (see below) | no | String |
| defaultValue | Default value for the property | String (see below) | no | (datatype-specific. See 'datatype' attribute) |
| designonly | Whether property should appear only in design-time property editors. | Boolean | no | false |
| hidden | Whether property should not appear in property editor. | Boolean | no | false |
| name | Name for this property | String | yes | none |
| readonly | Whether property should be read-only within property editor dialogs. | Boolean | no | false |
| required | If true, this property must have a value. | Boolean | no | false |
| sharedAs | Sharing name. If specified, indicates this is a property that is managed by the container application and whose value is potentially shared across multiple widgets. | String | no | none |
| transient | Whether the property will be used for transient/volatile values that should not be persisted. | Boolean | no | false |
| urlparam | URL parameter name for this property for when properties need to be passed as URL parameters | String | no | same as 'name' attribute |
| datatype_supplemental_attributes | Various attributes that provide additional information about the datatype, such as min and max values. Defined in Datatypes chapter. | |||
| pattern_attributes | (Only applies to JavaScript API descriptions.) Attributes 'getterPattern', 'setterPattern', 'registerHandlerPattern' and 'unregisterHandlerPattern'. Defined in Pattern attributes section. | |||
| scope | (Only applies to JavaScript API descriptions.) Whether this property applies to an object instance or is a class property. Defined in Common attributes section. | |||
| visibility | (Only applies to JavaScript API descriptions.) Intended visibility of this feature to other parts of the JavaScript application. Defined in Common attributes section. | |||
Attribute details
'datatype' attribute
The 'datatype' attribute specifies the allowed datatype(s) for the property's value. See the Datatypes chapterfor the detailed definition of this attribute.
'defaultValue' attribute
The defaultValue attribute specifies the default value for the property. If not specified, the default value for the property depends on the 'datatype' attribute. (See the discussion of the 'datatype' attribute in the Datatypes chapter.)
When the datatype is Date, the string value of the defaultValue attribute SHOULD be expressed in the format defined in RFC3339 - Date and Time on the Internet: Timestamps, with the one additional constraint that values MUST use uppercase "T" and "Z" characters for compatibility with ECMAScript5 (whereas RFC3339 says lowercase "t" and "z" are deprecated by allowed). The following show a small subset of the Date format values that are allowed:
2009-01-20T13:00Z | Jan. 20, 2009, 13:00 in UTC (coordinated universal time) |
2009-01-20T08:00-05 | Jan. 20, 2009, 8:00 in time zone 5 hours after UTC |
'designonly' attribute
A boolean. If true, this property SHOULD be visible and changeable within a design-time property editor, but SHOULD NOT be visible or changeable within run-time property editors. The distinction between "design-time" and "run-time" is left to the judgment of the tool provider; however, in some mashup scenarios, there might be a widget that requires two levels of customization, a first level that is done by administrators, and a second level is done by end-users. Widget properties that are meant to be seen only by administrators should have designonly="true". Default is false.
'hidden' attribute
A boolean. If true, this property SHOULD be hidden from the user and therefore tools SHOULD NOT display this property to the user in property editor dialogs. This attribute SHOULD be supported by conforming tools.
'name' attribute
The name attribute specifies the name for this property. Each different property name MUST be unique within the scope of its parent. 2009-06-23 Jon: Removed note about 'name' being fallback value for <title> because we already say this in discussion of <title> below.
'readonly' attribute
A boolean. If true, this property SHOULD be visible but read-only to the user. This attribute MUST be supported by conforming tools. Default is false.
'required' attribute
A boolean. If true, this property MUST have a value in order for the data set to be valid. This attribute MUST be supported by conforming tools. Default is false.
'sharedAs' attribute
A String. Identifies the property name to use for sharing purposes. By default, properties are private to a given widget; however, if a 'sharedAs' attribute is provided, then the property becomes a public property that the host application can choose to share with other widgets with matching 'sharedAs' attribute values.
It is valid to set the 'name' and 'sharedAs' attributes to the same value (e.g., <property name="location" sharedAs="location">), but a recommended approach that minimizes potential name conflicts and that maximizes correct property matching with other components is to set the 'sharedAs' attribute to a value that begins with a registered internet domain expressed in reverse order, such as <property name="location" sharedAs="org.example.properties.geolocation">. 2009-06-23 Jon: WG should review this wording.
'transient' attribute
The transient attribute. A boolean. This indicates that the property will be used for transient/volatile values that should not be persisted. This is false by default.
'urlparam' attribute
The urlparam attribute specifies the alternate name to use within URLs when the property is passed via a URL parameter.</span>
Attributes defined in the Datatypes chapter include: 'datatype', 'format', 'isInteger', 'minimum', 'maximum', 'min_length', 'max_length', 'min_items', 'max_items', 'pattern'.
Additional information
The optional <title> sub-element specifies a short description of this property, typically used as the label within property editor dialogs and/or tooltip within an editing environment. If not provided, then tools MAY choose to use other available information, such as the property name or the description, to construct the string that is presented in the property editor's UI.
If a <property> element appears in the metadata file such that it does not have either a <properties> element or a <childProperties> element as its parent, then it represents a normal property (i.e., as if it were a child of <properties>), not a child object property (i.e., as if it were a child of <childProperties>).
<properties>
The <properties> element holds zero or more <property> child elements.
For additional information about plural elements such as <properties>, refer to the
Plurals and Singular Elements chapter.
Schema
properties_element = element properties {
properties_content & properties_attributes & foreign_nodes
}
properties_content = (
descriptive_elements &
property_element*
)
properties_attributes = (
pattern_attributes &
name? & managed?
)
Child content
This element might contain any of the following sub-elements:
- descriptive_elements (various elements, such as <description> and <example>)
- Zero or more
<property>sub-elements.
Attribute summary
| Attribute | Description | Type | Required | Default |
|---|---|---|---|---|
| name | Optional name that defines a grouping name for a set of child properties. A tool might use the name attribute to establish property groups within a property editor dialog. |
String | no | none |
| managed | (Only applies to JavaScript API descriptions.) Whether the <property> child elements represent "managed properties" (see discussion below) |
Boolean | no | false |
| pattern_attributes | (Only applies to JavaScript API descriptions.) Attributes 'getterPattern', 'setterPattern', 'registerHandlerPattern' and 'unregisterHandlerPattern'. Defined in Pattern attributes section. | |||
Attribute details
'name' attribute
The optional name attribute defines a grouping name for a set of child properties that a tool might use to establish property groups within a property editor dialog. Each different group of properties (i.e., separate collections of properties each with their own <properties> parent element) might appear within different tabs within the property editor. For example, if name="Layout", then a tool might choose to include all of properties corresponding to child <property> elements within a "Layout" tab in the property editor.
Some tools may have multiple levels of tabs within a property editor. For example, perhaps there will be a first-level tab which shows "Basic" properties, and then a sub-tab within the "Basic" tab for "Sizing" properties. The recommmended convention for identifying hierarchical property groups is to use a double-colon sequence ("::") as the token separate string. For example, name="Basic::Sizing".
Here is an example of two <properties> elements. The second and third <properties> elements below use the double-colon sequence ("::") to identify a second level of property grouping:
<properties name="Layout"> <property name="leftMargin" .../> <property name="rightMargin" .../> </properties> <properties name="Basic::Color"> <property name="borderColor" .../> <property name="backgroundColor" .../> </properties> <properties name="Basic::Sizing"> <property name="width" .../> <property name="height" .../> </properties>
'managed' attribute
The optional managed attribute only applies to the JavaScript API use of properties, and does not apply to widget properties.
The 'managed' attribute is a boolean that indicates, if true, that the <property> child elements represent "managed properties", which means that the properties require getter and setter functions in order to retrieve or set the values for the properties. If false, then the properties can be retrieved and set without getter or setter functions, such as via JavaScript assignment statements.
2009-06-23 Jon: WG should review the write-up of the 'managed' property.
<childProperties>
The <childProperties> element addresses the case where a parent object adds properties to child objects. One common scenario is for this element is with layout container widgets. Layout container widgets sometimes look at particular properties on child widgets as input into layout calculations.
Developer tools should add any properties defined within a <childProperties> element onto the list of properties displayed in the child object's property editor.
Here is an example:
<widget name="BorderContainer">
<childProperties>
<property name="region" datatype="String" defaultValue="center">
<option name="left"/>
<option name="right"/>
<option name="top"/>
<option name="bottom"/>
<option name="center"/>
</property>
</childProperties>
...
</widget>
In the above example, the region property will be attached to all widgets that are immediately inside (contained by) the BorderContainer widget.
Schema
childProperties_element = element childProperties {
childProperties_content & childProperties_attributes & foreign_nodes
}
childProperties_content = (
descriptive_elements &
property_element*
)
childProperties_attributes = (
name?
)
Child content
This element might contain any of the following sub-elements:
- descriptive_elements (various elements, such as <description> and <example>)
- Zero or more
<property>child elements. For additional information about plural elements such as<childProperties>, refer to the Plurals and Singular Elements chapter.
Attribute summary
| Attribute | Description | Type | Required | Default |
|---|---|---|---|---|
| name | Optional name to uniquely identify this properties element |
String | no | none |
2009-06-23 Jon: Removed pattern_attributes from this element because we decided previously that pattern_attributes did not apply to widget features.
<config>
The <config> element is a grouping element that provides a detailed definition for a JavaScript object (or object literal) that can be referred to by a 'datatype' attribute. The <config> element lists the properties (via child <property> elements) that can exist on that object.
A primary use case for the <config> element is to describe an object (or object literal) that can be used as a parameter to a <method> or a <constructor>.
Here is an usage example:
<config name="MyClassConfigs">
<property name="firstname" datatype="String" required="true"/>
<property name="lastname" datatype="String" required="false"/>
<property name="email" datatype="String" required="false"/>
</config>
<class name="MyClass">
<constructor>
<parameter name="options" datatype="MyClassConfigs"/>
</constructor>
<method name="updateOptions">
<parameter name="options" datatype="MyClassConfigs"/>
</method>
</class>
Schema
config_element = element config {
config_content & config_attributes & foreign_nodes
}
config_content = (
descriptive_elements &
property_element* & properties_element*
)
config_attributes = (
name
)
Child content
This element might contain any of the following sub-elements:
- descriptive_elements (various elements, such as <description> and <example>)
- Zero or more
<property>as direct children of the<config>element - A single
<properties>child element, which in turn contains zero or more<property>child elements
Attribute summary
| Attribute | Description | Type | Required | Default |
|---|---|---|---|---|
| name | The name by which this <config> element can be referred by a 'datatype' attribute |
String | ues | none |
Additional information
For API metadata, the developer tool MUST implement scoping logic when searching for <config> elements that a 'datatype' attribute references. If the 'datatype' attribute is within an element that is a descendant of a <class>, <interface>, <mixin> or <singleton> element, then the developer tool MUST first search for <config> elements with the given name attribute that are either direct children of the given ancestor element or the direct children of a <configs> element that itself is a direct child of the given ancestor element.
If not found, then the developer tool MUST search for <config> elements with the given name attribute that are either direct children of the root <api> element or the direct children of a <configs> element that itself is a direct child of the root <api> element. The developer tool MUST ignore all other <config> elements in the metadata file, such as <config> elements that descend from other <class>, <interface>, <mixin> or <singleton> elements. The following example illustrates these scoping rules:
[01] <api ...> [02] <config name="config1">...</config> [03] <config name="config2">...</config> [04] <config name="config3">...</config> [05] <class name="class2" ...> [06] <config name="config2">...</config> [07] </class> [08] <class name="class1 ...> [09] <config name="config1">...<config> [10] <property name="prop1" datatype="config1" .../> [11] <property name="prop2" datatype="config2" .../> [12] <property name="prop3" datatype="config3" .../> [13] </class> [14] </api>
In the above case, the developer tool MUST do the following:
- Property
prop1must use the<config>element from line09instead of the line02because the developer tool MUST search the containing <class> element before searching the root <api> element. - Property
prop2must use the<config>element from line03and ignore the<config>element on line06because of the rule that the developer tool MUST ignore all<config>elements found in other <class>, <interface>, <mixin> or <singleton> elements. - Property
prop3must use the<config>element from line04because there was no<config>element with the nameconfig3in the containing <class> element.
For widget metadata, the developer tool MUST search for <config> elements with the given name attribute that are either direct children of the root <widget> element or the direct children of a <configs> element that itself is a direct child of the root <widget> element. The developer tool MUST ignore all other <config> elements in the metadata file.
It is important to set the name attribute to a value that will not conflict with other datatypes that might be used in other places within the metadata. Therefore, the name should not match any of standard datatype strings defined in the Datatypes chapter and any other names that might be used as a datatype (e.g., class names or the names of other the <config> elements.
Pattern attributes
This section describes the rules and processing model for the following "pattern attributes":
-
getterPattern -
setterPattern -
registerHandlerPattern -
unregisterHandlerPattern
These pattern attributes only apply to JavaScript APIs and are not applicable to OpenAjax Widgets.
Pattern attributes getterPattern and setterPattern attributes
Outside of mashup scenarios, collections of properties typically are managed internally within an Ajax library or component. The property management system might produce side effects due to property changes, such as sending notifications to other logic within the library or component.
The getterPattern and setterPattern attributes specify the name or name pattern for property getter and setter functions that correspond to a particular <property>. Both attributes are inheritable in that a given <property> element can inherit this attribute from one of its ancestor elements.
Developer tools can identify the getter and setter function names due to pattern recognition, which the
developer tool might leverage to provide more useful code completion features. getterPattern specifies a string pattern for how to invoke the function that retrieves a given property's value. setterPattern specifies a string pattern for how to invoke the function that sets a given property's value. For example:
<property name="Color" getterPattern="get{{property}}()" setterPattern="set{{property}}({{value}})"/>
which indicates that the getter function has the signature getColor() and the setter pattern has the signature setColor(colorvalue).
In the inheritance model, if getterPattern or setterPattern are specified on a given <property> element, the developer tool MUST use that attribute value; else, use the attribute value on the nearest ancestor element that has the given attribute.
registerHandlerPattern and unregisterHandlerPattern attributes
The registerHandlerPattern and unregisterHandlerPattern attributes apply to the <event> element and specifies the name pattern for the event handler registration and unregistration functions for that event. For example:
<event name="locationChange">
<handlerFunction registerHandlerPattern="{{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.
Detailed processing model
Two key characteristics distinguish these pattern attributes:
- The attributes can contain substitution strings (delimited by braces, as in
{{value}}) - The attributes are inheritable
For getterPattern and setterPattern, there are five substitution strings, all delimited by double-braces:
-
{{property}}: The name of the property (corresponds to the 'name' attribute on the<property>element) -
{{propertyUCFirst}}: Same as{{property}}, except that the first letter of the property name has been transformed into upper case (equivalent to thetoUpperCasemethod in ECMAScript 262) -
{{propertyLCFirst}}: Same as{{property}}, except that the first letter of the property name has been transformed into lower case (equivalent to thetoLowerCasemethod in ECMAScript 262) -
{{value}}: The value of the property. Often, this is a JavaScript literal value, such as null, a String, a Number, a Boolean, an Array literal or an Object literal. -
{{target}}: The JavaScript object (typically, an instance of a class) from which the getter or setter functions are available.
For registerHandlerPattern and unregisterHandlerPattern, there are four substitution strings, delimited by double-braces:
-
{{event}}: The name of the event (corresponds to the 'name' attribute on the <event> element) -
{{eventUCFirst}}: Same as{{event}}, except that the first letter of the event name has been transformed into upper case (equivalent to thetoUpperCasemethod in ECMAScript 262) -
{{eventLCFirst}}: Same as{{event}}, except that the first letter of the event name has been transformed into lower case (equivalent to thetoLowerCasemethod in ECMAScript 262) -
{{callback}}: The callback function (a JavaScript Function object).
getterPattern and setterPattern examples
For these example, assume the following:
- The JavaScript variable
MyWrapperObjectis the target object (i.e., the{{target}}) - The property's name (i.e., the
{{property}}) iscolor - The value to which the property will be set (i.e., the
{{value}}) is the string'blue'
Example:
<property getterPattern="{{target}}.{{property}}.get()"
setterPattern="{{target}}.{{property}}.set({{value}})"
...>
...
</property>
In the example above:
- The property getter function has the following signature:
MyWrapperObject.color.get(); - The property setter function has the following signature (where
'blue'shows how the value is passed):MyWrapperObject.color.set('blue');
Example:
<property getterPattern="{{target}}.getValue('{{property}}')"
setterPattern="{{target}}.setValue('{{property}}',{{value}})"
...>
...
</property>
In the example above:
- Runtime JavaScript logic can retrieve the property value via
var v = MyWrapperObject.getValue('color'); - Runtime JavaScript logic can set the property value via
MyWrapperObject.setValue('color','blue');
Example:
<property getterPattern="{{target}}.get{{propertyUCFirst}}Value()"
setterPattern="{{target}}.set{{propertyUCFirst}}Value({{value}})"
...>
...
</property>
In the example above:
- Runtime JavaScript logic can retrieve the property value via
var v = MyWrapperObject.getColorValue(); - Runtime JavaScript logic can set the property value via
MyWrapperObject.setColorValue('blue');
Inheritance and defaults
Attributes getterPattern, setterPattern, registerHandlerPattern and unregisterHandlerPattern are inheritable from their ancestor elements.
If either of getterPattern or setterPattern exists on a given <property> element, then that attribute takes precedence over any inherited values. If a given attribute does not exist on a given <property> element, then find the nearest ancestor element that has the given attribute and use the value from that ancestor. If no ancestors have the given attribute, then there is no value to inherit, which means that the attribute is unspecified.
Similarly, if either of registerHandlerPattern or unregisterHandlerPattern exists on a given <handlerFunction> element, then that attribute takes precedence over any inherited values.
If the attribute is unspecified after inheritance, then the developer tool SHALL assume that there is no corresponding function. For example, if getterPattern is unspecified, there is no corresponding getter function.
