Skip to content

You are not logged in. Register orLog In

start:

Document

OpenOfficeOpenOffice.org Registry Format (OOR)


Abstract

This document describes the registry format used for specifying, storing and updating configuration data for OpenOffice.org (OOo) components and applications. It is intended to demonstrate the concepts and facilities of the OOo Registry Format (OOR)and tries to give a quick understanding of how to write configuration schemas and how to use them for their components and applications.

It is a non-normative description targeted to application developers. The normative description of the format can be found at the appendices of this document containing the XMLSchema specifications of the OOR format.

Change History

Revision

Date

Author

Comments

0.1

28/11/01

Dirk Grobler

Initial draft containing basic concepts

0.2

02/12/01

Dirk Grobler

New sections for advanced concepts, introducing node context and value nodes as common attribute content holder.

0.3

12/12/01

Dirk Grobler

Set elements added and description for Access Control

0.4

19/12/01

Dirk Grobler

Update format description added.

0.5

18/01/02

Dirk Grobler

Combining Update and Fragment format to one format.

0.6

24/01/02

Dirk Grobler

Proof reading, incorporate feedback

0.7

12/03/02

Dirk Grobler

Definition for set extended. New documentation elements like annotation and labels.

0.8

19/03/02

Dirk Grobler

Dropped the Merged Format to reduce complexity. Reintroduced the default node-type for set elements to ensure backward compatibility with the existing format.

0.9

19/04/02

Dirk Grobler

Proof reading

0.9.1

28/04/02

Dirk Grobler

Any datatype added for backward compatibility with old config format.

0.9.2

06/05/02

Dirk Grobler

Update format uses know only oor:node for referencing nodes in the schema. This handling is less error-prone and simpler to understand.

0.9.3

25/07/02

Dirk Grobler

Enriched the component schema by adding versioning and new info elements like author and a deprecated flag.

0.9.4

11/20/02

Joerg Barfurth

Dropped oor:context from Update format; instead now always using oor:package. Descrption adjusted for packages and the update format root node.

0.9.5

02/14/03

Joerg Barfurth

No xsi:nil in schema. Many editorial changes. Added future directions. Updated all schemas to current OOo state.

0.9.6

05/22/03

Joerg Barfurth

Renamed update format root element to component-data (for namespace-correctness); removed spurious nillable attributes from schemas.

0.9.7

02/10/04

Joerg Barfurth

Formatting and typos corrected. Eliminated preformatted lines of excessive length.

0.9.8

06/10/05

Joerg Barfurth

Misplaced 'oor:' prefixes in examples corrected.

0.9.9

04/05/06

Stephan Bergmann

Introduced oor:op="fuse".



Contents

Introduction

Conceptual Framework

Registry Object Model
Registry Document Types

Basis Concepts - DataSource Configuration in OOo

Groups and Properties
Sets and Templates
Re-Usage of Templates
Localization of Properties
Extensible Nodes
Property Constraints
Annotations
Versioning

Advanced Concepts

Layering and Merging
Access Control

Appendices

A. Registry Types
B. Registry Schema Format
C. Registry Update Format


Introduction


There are plenty of file formats and protocols for storing and handling configuration data. There are industry standards like LDAP, binary registry formats, APIs like the JAVA Preferences API and many more. They are all based on the concept of storing key-value pairs and provide a hierarchy to organize these atomic entries.

It is not the intention of reinventing the wheel and providing yet another configuration format, instead of reusing an existing one. The intention is rather to have a format which is compatible to existing standards or allows, at least, an easy mapping to existing formats and also meets the requirements for the OpenOffice.org applications in their different environments. These requirements include:

  • Availability on all supported platforms of OpenOffice.org,

  • Capability of efficient storing and retrieval of thousands of configuration key-value pairs,

  • Support for multiple backends, e.g. file-based or LDAP,

  • Support for multiple layers with merging capabilities of default and user-defined settings,

  • Human readable, which is important for product support,

  • Easy to define and use for application developers.

The targeted audience for this document are application developers and architects, who need to know how to describe and compile an application configuration schema with OOR. Therefore this document is designed more like a Programmer's manual than a functional specification. After providing some background by describing the design principles in the first section, the following sections describe the concepts used by means of an example illustrating most of the facets of the registry document format. The appendices contain the XMLSchema definitions for the OOR format(s), which can be viewed as a reference specification.

Conceptual Framework


The OpenOffice.org Registry format is an XML based meta format. The format is divided into two sub-formats. One of the sub-formats is the Registry Component Schema Format. It defines reusable node types called Templates, and a default configuration hierarchy. The other one is the Registry Update Format, which is used to specify difference and store updates relative to a tree. The full meaning of such an update document only be discovered relative to a configuration schema.

The schema document is specified in a way, that it can be provided by the developer or author of the schema and be used unchanged in any deployment. All things that vary between products, localizations, installations or users are specified in layer documents which employ the update format.

There also is a virtual third sub-format, which can be used to describe the results of a merging process applied to a configuration schema and several layers of updates. This format is called the Registry Merged Format. It is virtual in that the XML Schema for this is not documented and there are currently no use cases where this format would be required. But if a means to store or transport merged configuration hierarchies is required, such a format can be constructed from the building blocks the current formats provide.

This section provides a high-level description of the registry object model, which is the basic conceptual model for the registry document format, and of the OOR sub-formats themselves, which are derived from that model.

The following table lists the XML namespaces used by the OOR format and their prefixes.

Prefix

Description

Namespace

oor

For elements and attributes, that are particular to the OOR formats.

http://openoffice.org/2001/registry

xs

For elements and attributes, which are reused from the XMLSchema definition.

http://www.w3.org/2001/XMLSchema

xsi

For elements and attributes which are reused from the XMLSchema instance definition. These elements and attributes are used only in the update format.

http://www.w3.org/2001/XMLSchema-instance



According to the schema definition for OOR, only root elements MUST have a namespace qualifier. All inner (local) elements don't use a qualifier as they are qualified within their context. Throughout the documentation, elements and attributes specified by OOR are not prefixed with the namespace qualifier. Only elements imported from other namespaces are qualified.

Registry Object Model

The Registry Object Model describes a hierarchical data structure. It offers two kinds of elements. On the one hand there are nodes, which combine related elements into logical groupings. On the other hand there are properties, which hold the actual data values. Nodes are the inner elements of the tree, while properties are the leaves of the tree.

All elements have a well-defined type. The type of a property corresponds directly to the type of data it can hold, while the type of a node depends (recursively) on the types of the child nodes and properties it contains and the way those are combined. A node type may be described in the schema as a separate named entity, called a template, or it may be implicit in the definition of a node. Templates allow reusing a type in multiple places in the schema and dynamic creation of nodes of a given type.

The following kinds of elements can be used to build a configuration schema:

Properties

Properties, specified by <prop>tags, hold the actual data values. They must have one of a number of supported data types.

The following basic data-types are supported:

xs:string

Plain Text (Sequence of [printable] Unicode characters)

xs:boolean

Boolean value (true/false)

xs:short

16 - bit integer number

xs:int

32 - bit integer number

xs:long

64 - bit integer number

xs:double

floating point number (value range as for IEEE 64-bit double)

xs:hexBinary

Sequence of uninterpreted octets, hex encoded


Please note that xs:hexBinary values should be used only for small chunks of data (< 256 Byte) that cannot easily be represented otherwise or stored elsewhere. The configuration service is not optimized to handle large BLOBs efficiently. Instead it is recommended to store links (e.g. URLs) to greater chunks of binary data. For example a small icon can be stored in the configuration, but a larger image or an entire icon suite is better stored elsewhere.

Also supported are lists (ordered sequences) of each of the basic types. [NOTE: This means that the lists must be homogeneous – mixed lists are not supported]. The configuration treats lists as atomic data-types -- there is no support for accessing lists element-wise or merging the contents of lists.
List item values are generally separated by whitespace. This is a natural separator, which is used for XMLSchema list types as well. This works well for numeric or boolean types. For lists of strings or binary values this separator can be a problem, if the list contains zero-length values or strings that contain whitespace themselves. Think, for example, of a list of continents like 'Europe Africa South America'; here the whitespace separation doesn't work, as 'South America' itself contains a whitespace character. You can resolve this issue by specifying a separator attribute for each value tag of the property. The list of continents then might be separated by comma: 'Europe,Africa,South America'.

In addition, a property may be characterized as nillable (or not nillable). If it is nillable, it may assume the special value NIL, which indicates the absence of any particular value. NIL is different from any legal value. In particular, a string/list/binary property having zero length is not NIL. Nillable properties are sometimes also called optional. By default, each property is nillable.

The schema may also provide a default value for a property. The default value must be of the appropriate data-type and should fulfill the constraints. A default value is not required, even for properties the are not nillable.

An additional data-type oor:any can be used within the schema (particularly within templates). A property of this type may not have a default value. In a layer such a property can be given a non-NULL value of any of the types enumerated above.

To support internationalization, properties may be marked localized in the schema. Localized properties (and only localized properties) may assume different values for different locales. This is particularly important for text strings intended for UI display, but may apply to other settings as well. The locale is one of the parameters that is used to select a configuration. Only one language-neutral default value can be provided for a localized property. Locale-specific standard values should be provided in an appropriate layer.

Group-Nodes

Group-Nodes - their element tag in the schema is <group> - are the basic building blocks for organizing related data items. A top-level Component-Node (see below) is a special kind of group-node. A group-node groups together a number of child nodes and a list of properties. The child nodes and properties (sometimes collectively called members) are identified by their names. The type of a group-node is determined by the number of children and properties within the group, their names and their types.

Member names must be unique within a group. Each member property may be of a different type, but that type is fixed by the schema and cannot change (unless the schema specifies type any). To change a group-node means to change one of its members. Any kind of node can be a member of a group-node. By nesting groups within groups within groups and so on, a fixed hierarchical data structure can be described.

A group may be marked as extensible. The list of properties in an extensible group can be extended with new properties in a layer. This is useful in situations, where you need to have objects that may have additional characteristics at runtime represented by nodes in a registry layer. An extensible group allows adding additional properties to a node in a layer. It is also possible to remove those settings later in the layer were they were added. Properties declared in the schema cannot be removed. Otherwise dynamically added properties behave as if defined in the schema as nillable, non-localized property of type any.

Set-Nodes

Set-Nodes – using schema element tag <set> - provide a way to describe dynamic parts of the configuration tree. New nodes can be added to and removed from a set in a layer. Thus a set-node is a container of node items. The type of the node items is provided by a node-type attribute or as list of <item> elements, where each item defines a possible node-type. The node-type is a reference to a template of that name in a component schema. A reference to a different component schema is effected by supplying a component attribute that supplies the fully qualified component name. Otherwise the reference is to a template in the same component schema.

The items contained in a set are identified by their name. The name must be unique within the set. The type of the set node is determined by its node-type or its list of item node-types alone. The number and names of child nodes may change dynamically in layers. No actual children may be given in the schema.

A set can be changed by removing existing nodes or by inserting new nodes. Nodes to be inserted must conform with one of the allowed item types specified for the container.

The node-type attribute for the set is required even when further items are defined and specifies a default type for an item. Items of that type don't need to specify it in the layer where they are added. Items of a type other than the default type need to specify theit node type in the layer where they are first added.

Sets may be used to build recursive data structures, if their node-type directly or indirectly contains a set supporting the same node-type.

Like group-nodes, sets can be declared as extensible, which allows adding (dynamic) properties in layers.

Generic Nodes [This feature is planned as an extension, but not implemented yet]

Generic Nodes – using schema element tag <node> - provide a way to describe parts of the configuration tree, that are not controlled by a schema. New nodes and properties can be freely added to and removed from a generic node. Child nodes of a generic node are generic nodes themselves. A predefined hierarchy of generic nodes with some properties can be given in the schema. These nodes will be marked as mandatory (non-removable) in the merged tree.

Functionally a generic node can be simulated by a template type which is a set that has itself as item-type and is extensible (allows adding properties). Only the ability to define a skeleton hierarchy with predefined, typed properties in the schema is a new feature. Generic nodes are needed to interoperate with other configuration systems that have less strict rules for schema usage. For that use case it is also helpful, to have this type as a builtin feature, rather than having to rely on an explicite template.

Component-Nodes

At the outermost level the configuration is divided into components. A component is a collection of configuration data, that may be installed or used independently of other components. Often a component is associated with a particular software component, module or product. Some components may be intended to be shared between several cooperating pieces of software.

A component is characterized by a component configuration schema, also called component schema. The component schema describes a single hierarchy of component specific settings. The root node of this hierarchy is called the component node. The component schema also contains the set of node templates of the component. A component schema may depend upon another component schema. Currently, this dependency can either be purely semantic, i.e., a client accessing settings of a particular component schema regularly needs access to another component schema as well or it can be utilized in the component schema to import and (re)use node templates from another component schema. These dependency relationships must not be circular. If a dependency exists of one component schema on another, then the latter is required to be installed when the dependent schema is installed.


Within the object model, a component-node is a special, non-extensible group-node. It can act only as root node of the whole component configuration hierarchy. When generic nodes will be introduced, there will also be a way to construct generic components, i.e. whose component-node is generic.

Packages

Components contain the settings for a part of an application. The sum of all component settings is called the application or system registry. Within the registry the components are organized into packages. Each package may contain several components and sub-packages. This concept is well known in other areas like JAVA and UNO. On a file system, a package might be represented by a folder and a component by a single OOR xml file. Packages form the outer hierarchy of components. A package name and a local subpackage names are combined using a dot ('.') to obtain the full name of the subpackage. A component name and the name of the package it belongs to are similarly joined to form the fully qualified component name (FQCN). For example package=org.openoffice.Office and name=DataAccess yield the FQCN component=org.openoffice.Office.DataAccess.

Registry Document Types

OOR offers two different kinds of formats, the Registry Component Schema Format (xcs) and the Registry Update Format (xcu). The first format serves as configuration definition format, while the latter one is intended to store instances of configuration data.

Note: 'xcs' and 'xcu' are the default file extensions assigned to the formats.

Registry Component Schema Format

The Registry Component Schema Format is a meta format for defining the configuration hierarchy, reusable node types and key value-pairs called properties for a single component or module. Properties may have default values assigned by the schema. In addition, it is possible to provide documentation for each building block (element) of the hierarchy and to set constraints on properties. In a layered view of the registry, the component schema can be regarded as immutable base layer, providing the skeleton of the hierarchy with some default settings. Any kind of dynamic or installation-dependent data, like localized values or items of a set are not part of the schema. Defaults for such data cen be provided in an additional layer document, which uses the Registry Update Format described in the next section.

Registry Update Format

One design goal of OOR is to enable the storage of configuration settings in several layers. A cluster of configuration settings in a layer is also called preferences. Different layers may define global defaults, installation-specific settings, group preferences or policies and individual user preferences.

A typical example is the OpenOffice.org application itself, which supports a multi-user installation. All default settings (the default layer) are stored in a shared folder, often on a network server, which is available to all users of the installation. The user preferences are stored in a separate user folder (user layer) in the user's home directory on on their workstation.

Such layers are stored using the update format, which contains only those settings which differ, are new or hidden compared to a default configuration.

When the application reads settings out of the registry on behalf of a user, the settings from the default and user layers are merged by applying the differences stored in the user layer to the default data obtained from the default layer and the schema. A single merged tree is then passed to the application. Any modifications done by the user to this merged tree are translated into changes to the user layer that affect the merged tree in the desired way. A user is also able to reset settings to default settings, which means that settingsare removed from the user layer so that the corresponding default settings are visible again.

This way of storing and merging configuration data as differences is efficient in terms of the overall data size stored for an individual user. Another benefit can be found on the administration side. Changing a setting in the default layer will automatically take effect for all users that have not overwritten the settings with their own preferences.

Another difference compared to the Registry Component Schema Format is the nature of the data stored in the Registry Update Format. While the schema provides a set of type definitions and a fixed data hierarchy, the update format contains dynamic data, which can expand the hierarchy (set items) in each layer. One special use of layers is that they can contain value that are adjusted (e.g. translated) for different locales.

Basic Concepts - DataSource Configuration in OpenOffice.org


OpenOffice.org contains a component for managing data-sources and the access to databases. The configuration settings of this component are a good example to illustrate most of the concepts found in the OOR format. The schema has been stripped at some places to focus only the necessary items for illustration of the concepts. Below you find component schema of the 'DataSource' component.

'DataSource' component schema, DataSource.xcs

<?xml version="1.0" encoding="utf-8"?>
<oor:component-schema oor:name="DataAccess" oor:package="org.openoffice.Office" 
 xsi:schemaLocation="http://openoffice.org/2001/registry component-schema.xsd" 
 xmlns:xs="http://www.w3.org/2001/XMLSchema" 
 xmlns:oor="http://openoffice.org/2001/registry" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
 xml:lang='en-US'>
  <import oor:component="org.openoffice.Office.Common"/>
  <templates>
    <group oor:name="DataSettings">
      <prop oor:name="Filter" oor:type="xs:string">
        <value/>
      </prop>
      <prop oor:name="ApplyFilter" oor:type="xs:boolean">
        <value>false</value>
      </prop>
      <prop oor:name="Order" oor:type="xs:string">
        <value/>
      </prop>
      <prop oor:name="RowHeight" oor:type="xs:int"/>
      <prop oor:name="TextColor" oor:type="xs:int"/>
      <prop oor:name="TextLineColor" oor:type="xs:int"/>
      <prop oor:name="CharacterEmphasis" oor:type="xs:short"/>
      <prop oor:name="CharacterRelief" oor:type="xs:short"/>
      <node-ref oor:name="Font" oor:node-type="Font" oor:component="org.openoffice.Office.Common"/>
    </group>
    <group oor:name="Column">
      <prop oor:name="FormatKey" oor:type="xs:int"/>
      <prop oor:name="FormatString" oor:type="xs:string"/>
      <prop oor:name="FormatLocale" oor:type="xs:string"/>
      <prop oor:name="Align" oor:type="xs:int"/>
      <prop oor:name="Width" oor:type="xs:int"/>
      <prop oor:name="Position" oor:type="xs:int"/>
      <prop oor:name="Hidden" oor:type="xs:boolean">
        <value>false</value>
      </prop>
      <prop oor:name="Control" oor:type="xs:hexBinary"/>
      <prop oor:name="HelpText" oor:type="xs:string"/>
      <prop oor:name="ControlDefault" oor:type="xs:string"/>
    </group>
    <group oor:name="Table">
      <node-ref oor:name="Settings" oor:node-type="DataSettings"/>
      <set oor:name="Columns"><item oor:node-type="Column"/></set>
    </group>
    <group oor:name="Query">
      <prop oor:name="Command" oor:type="xs:string"/>
      <prop oor:name="EscapeProcessing" oor:type="xs:boolean">
        <value>true</value>
      </prop>
      <prop oor:name="UpdateTableName" oor:type="xs:string"/>
      <prop oor:name="UpdateSchemaName" oor:type="xs:string"/>
      <prop oor:name="UpdateCatalogName" oor:type="xs:string"/>
      <prop oor:name="LayoutInformation" oor:type="xs:hexBinary" 
oor:nillable="false"/>
      <node-ref oor:name="Settings" oor:node-type="DataSettings"/>
      <set oor:name="Columns" oor:node-type="Column"/>
    </group>
    <group oor:name="Bookmark">
      <prop oor:name="DocumentLocation" oor:type="xs:string"/>
    </group>
    <group oor:name="DataSourceDescription" oor:extensible=”true”>
      <prop oor:name="URL" oor:type="xs:string"/>
      <prop oor:name="IsPasswordRequired" oor:type="xs:boolean">
        <value>true</value>
      </prop>
      <prop oor:name="TableFilter" oor:type="oor:string-list">
        <value>%</value>
      </prop>
      <prop oor:name="TableTypeFilter" oor:type="oor:string-list"/>
      <prop oor:name="NumberFormatSettings" oor:type="xs:hexBinary"/>
      <prop oor:name="User" oor:type="xs:string"/>
      <prop oor:name="LoginTimeout" oor:type="xs:int"/>
      <prop oor:name="SuppressVersionColumns" oor:type="xs:boolean">
        <value>true</value>
      </prop>
      <prop oor:name="LayoutInformation" oor:type="xs:hexBinary" 
oor:nillable="false"/>
      <set oor:name="Tables" oor:node-type="Table"/>
      <set oor:name="Queries" oor:node-type="Query"/>
      <set oor:name="Bookmarks" oor:node-type="Bookmark"/>
    </group>    
    <group oor:name="DriverPooling">      
      <prop oor:name="Enable" oor:type="xs:boolean">
        <value>true</value>
      </prop>
      <prop oor:name="Timeout" oor:type="xs:int"/>
    </group>
  </templates>
  <oor:component>
    <group oor:name="DriverManager">
      <prop oor:name="DriverPrecedence" oor:type="oor:string-list">
        <value oor:separator=";">com.sun.star.comp.sdbc.ODBCDriver;
com.sun.star.comp.sdbc.JDBCDriver</value>
      </prop>
    </group>
    <group oor:name="ConnectionPool">
      <prop oor:name="EnablePooling" oor:type="xs:boolean">
        <value>true</value>
      </prop>
      <set oor:name="DriverSettings" oor:node-type="DriverPooling"/>
    </group>
    <set oor:name="DataSources" oor:node-type="DataSourceDescription"/>
    <group oor:name="DriverSettings">      
      <group oor:name="com.sun.star.comp.sdbc.MozabDriver">
        <group oor:name="MozillaPreferences">
          <prop oor:name="ProfileName" oor:type="xs:string"/>
        </group>
        <group oor:name="ColumnAliases">
          <prop oor:name="FirstName" oor:type="xs:string" oor:localized="true"/>
          <prop oor:name="LastName" oor:type="xs:string" oor:localized="true"/>
          <prop oor:name="DisplayName" oor:type="xs:string" oor:localized="true"/>
          <prop oor:name="NickName" oor:type="xs:string" oor:localized="true"/>
          <prop oor:name="PrimaryEmail" oor:type="xs:string" oor:localized="true"/>
          <prop oor:name="SecondEmail" oor:type="xs:string" oor:localized="true"/>          
        </group>
      </group>
    </group>
    <group oor:name="FormSearchOptions">
      <prop oor:name="SearchType" oor:type="xs:string">
        <value>text</value>
      </prop>
      <prop oor:name="SearchPosition" oor:type="xs:string">
        <value>anywhere-in-field</value>
      </prop>
      <prop oor:name="SearchHistory" oor:type="oor:string-list" />
      <prop oor:name="IsSearchAllFields" oor:type="xs:boolean">
        <value>false</value>
      </prop>
      <prop oor:name="IsUseFormatter" oor:type="xs:boolean">
        <value>true</value>
      </prop>
      <prop oor:name="IsBackwards" oor:type="xs:boolean">
        <value>false</value>
      </prop>
      <prop oor:name="IsWildcardSearch" oor:type="xs:boolean">
        <value>false</value>
      </prop>
      <prop oor:name="IsUseRegularExpression" oor:type="xs:boolean">
        <value>false</value>
      </prop>
      <prop oor:name="IsSimilaritySearch" oor:type="xs:boolean">
        <value>false</value>
      </prop>
      <prop oor:name="IsLevenshteinRelaxed" oor:type="xs:boolean">
        <value>false</value>
      </prop>
      <prop oor:name="LevenshteinOther" oor:type="xs:short">
        <value>2</value>
      </prop>
      <prop oor:name="LevenshteinShorter" oor:type="xs:short">
        <value>2</value>
      </prop>
      <prop oor:name="LevenshteinLonger" oor:type="xs:short">
        <value>2</value>
      </prop>
      <prop oor:name="IsMatchCase" oor:type="xs:boolean">
        <value>false</value>
      </prop>
      <prop oor:name="IsUseAsianOptions" oor:type="xs:boolean" >
        <value>false</value>
      </prop>
      <!-- Omitted: group oor:name="Japanese" -->
    </group>
  </oor:component>
</oor:component-schema>
The component schema contains the following major sections. <import> specifies a component, which is needed during deployment to import type definitions (AKA templates). <templates> specifies reusable type definitions used within the schema. These definitions are also available for other components. The last section is <component>, which defines the default configuration hierarchy for the component.

Groups and Properties

The simplest way to define a component schema is to build a configuration hierarchy by using group-nodes and properties. The component hierarchy of the given example knows four kinds of first level child nodes ('DriverManager', 'ConnectionPool', 'DataSources' and 'DriverSettings'). Except for 'DataSources' they are all defined as group-nodes, which means that the list of properties and list of child nodes is fixed by the default tree, while the content of the properties may be changed in a layer. Only 'DataSources' is a set-node, which allows additional modifications of the node structure like adding or removing child nodes at runtime. You will find more information about set-nodes in the next chapter.

Group-node definition of nodes 'DriverManager' and 'ConnectionPool'

  <oor:component>    
    <group oor:name="DriverManager">
      <prop oor:name="DriverPrecedence" oor:type="oor:string-list">
        <value oor:separator=";">com.sun.star.comp.sdbc.ODBCDriver;com.sun.star.comp.sdbc.JDBCDriver</value>
      </prop>
    </group>
    <group oor:name="ConnectionPool">
      <prop oor:name="EnablePooling" oor:type="xs:boolean">
        <value>true</value>
      </prop>
      <set oor:name="DriverSettings" oor:node-type="DriverPooling"/>
    </group>
    ...
   </oor:component>

If you look at the example above, you can see that the group-node 'DriverManager' contains only one property, 'DriverPrecedence', and no sub-nodes. 'DriverPrecedences' is actually a key-value pair of type string-list, saying that the content of the property contains a sequence of elements of the basic type xs:string. The separator for the list elements is defined by the attribute separator. 'DriverPrecedences' has a default value providing an initial list of drivers, which should be considered for resolving database driver URLs to establish driver connections via the driver-manager.

The second group given in the example is the group-node 'ConnectionPool', which specifies a node having one property 'EnablePooling' and a sub-node of type set. Of course youz can nest group nodes within group nodes as well. The property 'EnablePooling' is of the basic type xs:boolean. It has a default value expressing that connection pooling should be initially enabled.

Each structuring element has mandatory attributes. The name of each element (property, group-node, set-node) is required, as this is the identifier of sub-nodes or properties. The name of an element MUST be unique within the list of child elements.

Sets and Templates

In the previous paragraph, a set-node with the name 'DriverSettings' was mentioned. Sets are dynamic nodes enabling applications to add and remove child nodes during runtime. The only restriction is that the sub-nodes of a set MUST belong to one of the given node-types. The example below illustrates the definition of the template 'DriverPooling' and the definition of the set 'DriverSettings', of which sub-nodes MUST be instances of the previously defined template 'DriverPooling'.

Set-node definition of node 'DriverSettings' and using the template 'DriverPooling'

  <templates>
    ...
    <group oor:name="DriverPooling">
      <prop oor:name="Enable" oor:type="xs:boolean">
        <value>true</value>
      </prop>
      <prop oor:name="Timeout" oor:type="xs:int"/>
    </group>
  </templates>
  <component>    
    <group oor:name="DriverManager">
      <prop oor:name="DriverPrecedence" oor:type="oor:string-list">
        <value oor:separator=";">com.sun.star.comp.sdbc.ODBCDriver;
com.sun.star.comp.sdbc.JDBCDriver</value>
      </prop>
    </group>
    <group oor:name="ConnectionPool">
      <prop oor:name="EnablePooling" oor:type="xs:boolean">
        <value>true</value>
      </prop>
      <set oor:name="DriverSettings" oor:node-type="DriverPooling"/>
    </group>
    ...
   </component>

Templates need to be defined in the <templates> section of the component schema. Template 'DriverPooling' describes a group-node containing two properties. The elements of a set, which must be instances of a template supported by that set, can be provided only in an Update Document. The Schema Format does not allow specifying sub-nodes in a set. Sets are meant to hold dynamically changing data, which conceptually does not belong into a schema. Elements can be provided in predefined Update Documents during deployment or they can be added or removed at runtime.

An update tree for 'DriverSettings' containing 'default' elements, which could be provided at deployment time, could look as in the following example:

Update tree fragment containing initial sub-nodes for the set-node 'DriverSettings'

<?xml version="1.0" encoding="utf-8"?>
<oor:component-data oor:name="DataAccess" oor:package="org.openoffice.Office" 
 xsi:schemaLocation="http://openoffice.org/2001/registry/component-update.xsd" 
 xmlns:xs="http://www.w3.org/2001/XMLSchema" 
 xmlns:oor="http://openoffice.org/2001/registry" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <node oor:name="ConnectionPool">
    <node oor:name="DriverSettings">      
      <node oor:name="com.sun.star.comp.sdbc.mozaddressbook.Driver" oor:op='replace'>
        <prop oor:name="Timeout">
          <value>60</value>
        </prop>
      </node>
      <node oor:name="com.sun.star.comp.sdbc.ado.ODriver" oor:op='replace'>
        <prop oor:name="Enable">
          <value>false</value>
        </prop>
      </node>
      <node oor:name="com.sun.star.comp.sdbc.JDBCDriver" oor:op='replace'>
        <prop oor:name="Timeout">
          <value>60</value>
        </prop>
      </node>
      <node oor:name="com.sun.star.comp.sdbc.ODBCDriver" oor:op='replace'>
        <prop oor:name="Timeout">
          <value>60</value>
        </prop>
      </node>
    </node>
  </node>    
</oor:component-data>

In the example you find four sub-nodes of type 'DriverPooling'. They describe, how connection pooling should be applied to certain drivers. The drivers are identified by their implementation names like 'com.sun.star.comp.sdbc.ODBCDriver'. Only the 'Timeout' property is set for most driver. The other property 'EnablePooling' does not appear, as the default setting within the template should be applied. For one entry this is reversed.

Each sub-entry of 'DriverSettings' contains an operation ( op ) attribute. This piece of runtime information defines in which way the merging should be executed. In this specific case, each node replaces nodes of the same name in a base layer. More details about operations can be found in the chapter 'Layering and Merging'.

All nodes and properties are identified by their name. This name and the location within the hierarchy allows to identify the equivalent element in the component schema. Therefore the type of a node or property need not be specified in the update format. The update format knows only nodes and their attributes. The root component-data node corresponds to the component node of the schema. Its name is the name of the component and it contains a package specifying the package to which the component belongs. These attributes mean the same here as on a component-schema node.

Another example for the usage of sets is illustrated in the menu example below. A menu is a recursive structure, where a menu can contain several popup menus, which themselves may contain menu-items, menu-separators and/or further sub-menus. This is modeled by a template which contains a set that allows multiple node-types. One of those node-types is the template itself, so this template is recursive. The set specification of the 'menupopup' contains a list of possible child types: 'menuitem', 'menuseparator' and (recursively) 'menu', with 'menuitem' being the default.

Recursive definition of menus

  <templates>
      <group oor:name="menu">
          <prop oor:name="id" oor:type="xs:int"/>
          <prop oor:name="label" oor:type="xs:string" oor:localized="true"/>
          <set oor:name="menupopup" oor:node-type="menuitem">
               <item oor:node-type="menuseparator"/>
               <item oor:node-type="menuitem"/>
               <item oor:node-type="menu"/>
          </set>
      </group>
      <set oor:name="menubar" oor:node-type="menu"/>
      <group oor:name="menuitem">
          <prop oor:name="id" oor:type="xs:int"/>
          <prop oor:name="helpid" oor:type="xs:int"/>
          <prop oor:name="label" oor:type="xs:string" oor:localized="true"/>
      </group>
      <group oor:name="menuseparator"/>
  </templates>

All possible child element types are listed in the item-elements of node 'menupopup'. Each listed node-type must be unique within the item list. The node-type attribute of the set element identifies the default item for creation of new properties. If any items are present at all the node-type attribute MUST identify one of them, otherwise the schema definition is invalid. (This might be changed to be more lenient and not require the default to be listed as an item). This condition can't be validated from the XML Schema or DTD; schema authors must keep this condition in mind.

Re-Use of Templates

Templates are node fragments that can be reused. We already encountered the most frequent use case for this: A template-node serves as a pattern for the creation of sub-nodes of a set. Another use case for templates are node references (node-ref). A node-ref is a pointer to a template-node associated with a unique name. At runtime, such a node-ref is expanded to the structure of the referenced template-node. It inherits the characteristics and defaults of the template node and can be accessed and modified like any other node in the configuration hierarchy. Node references reduce the documentation effort and help representing similar things consistently within the configuration schema, as the definition of the particular node is done only once in the template section of the component configuration schema. The example below illustrates the use of node references.

node-ref example 'Bibliography'

...     
  <templates>
    <group oor:name="DataSource">
      <prop oor:name="DataSourceName" oor:type="xs:string"/>
      <prop oor:name="Command" oor:type="xs:string"/>
      <prop oor:name="CommandType" oor:type="xs:short"/>
      <set oor:name="Fields" oor:node-type="FieldAssignment"/>
    </group>
    <group oor:name="FieldAssignment">
      <prop oor:name="ProgrammaticFieldName" oor:type="xs:string"/>
      <prop oor:name="AssignedFieldName" oor:type="xs:string"/>
    </group>    
  </templates>
  <component>
    <group oor:name="Bibliography">
      <prop oor:name="BeamerHeight" oor:type="xs:int"/>
      <prop oor:name="ViewHeight" oor:type="xs:int"/>
      <prop oor:name="QueryText" oor:type="xs:string"/>
      <prop oor:name="QueryField" oor:type="xs:string"/>
      <node-ref oor:name="CurrentDataSource" oor:node-type="DataSource"/>
      <set oor:name="DataSourceHistory" oor:node-type="DataSource"/>
    </group>
  </component>
... 

Expanded 'Bibliography' component data without node-ref

...     

  <component>
    <group oor:name="Bibliography">
      <prop oor:name="BeamerHeight" oor:type="xs:int"/>
      <prop oor:name="ViewHeight" oor:type="xs:int"/>
      <prop oor:name="QueryText" oor:type="xs:string"/>
      <prop oor:name="QueryField" oor:type="xs:string"/>
      <group oor:name="CurrentDataSource">
        <prop oor:name="DataSourceName" oor:type="xs:string"/>
        <prop oor:name="Command" oor:type="xs:string"/>
        <prop oor:name="CommandType" oor:type="xs:short"/>
        <set oor:name="Fields" oor:node-type="FieldAssignment"/>
      </group>
      <set oor:name="DataSourceHistory" oor:node-type="DataSource"/>
    </group>
  </component>
... 

The 'Bibliography' component of OOo application stores its settings within the DataAccess component schema. It is, itself, a data-source with additional settings for the UI representation. One sub-node of the 'Bibliography' node specifies settings for the 'CurrentDataSource' used to store and retrieve bibliographic data. This node is of the node-type 'DataSource', which is defined in the template section and is also used elsewhere, e.g. as element type of set 'DataSourceHistory'. 'CurrentDataSource' inherits all characteristics of that template-node. The component schema behaves as if it contained the expanded hierarchy shown in the second part of the example. But instead of repeating everything from the template node and duplicating the definition effort, the template node is simply referenced. This mechanism helps to keep the schema definition compact and free of redundancies.

Another way to avoid redundancy is to reuse templates across component schema boundaries. OOR allows importing existing component schemas. A prerequisite is that the imported component schema is available at both deployment and runtime to access, instantiate and validate imported template definitions. To import a template from another component, you have to specify two things:

  • an import element in the component schema pointing to the component schema, which contains the template.

  • a component attribute that accompanies the node-type at the node-ref or set element, which references the component which owns the template. The component named in this attribute must also be imported in the same component-schema.

Importing a Font template for the DataAccess component schema

<?xml version="1.0" encoding="utf-8"?>
<oor:component-schema oor:name="Common" oor:package="org.openoffice.Office"
  xmlns:oor="http://openoffice.org/2001/registry" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  xml:lang="en-US">
  <templates
    ...
    <group oor:name="Font">
        <prop oor:name="Name" oor:type="xs:string"/>
        <prop oor:name="Height" oor:type="xs:short"/>
        <prop oor:name="Width" oor:type="xs:short"/>
        <prop oor:name="StyleName" oor:type="xs:string"/>
        <prop oor:name="Family" oor:type="xs:short"/>
        <prop oor:name="CharSet" oor:type="xs:short"/>
        <prop oor:name="Pitch" oor:type="xs:short"/>
        <prop oor:name="CharacterWidth" oor:type="xs:double"/>
        <prop oor:name="Weight" oor:type="xs:double"/>
        <prop oor:name="Slant" oor:type="xs:short"/>
        <prop oor:name="UnderLine" oor:type="xs:short"/>
        <prop oor:name="Strikeout" oor:type="xs:short"/>
        <prop oor:name="Kerning" oor:type="xs:boolean"/>
        <prop oor:name="WordLineMode" oor:type="xs:boolean"/>
        <prop oor:name="Type" oor:type="xs:short"/>
    </group>
   ...
  </templates>
  <component>
    ...
  </component>
</oor:component-schema>
<?xml version="1.0" encoding="utf-8"?>
<oor:component-schema oor:name="DataAccess" oor:package="org.openoffice.Office" 
 xsi:schemaLocation="http://openoffice.org/2001/registry component-schema.xsd" 
 xmlns:xs="http://www.w3.org/2001/XMLSchema" 
 xmlns:oor="http://openoffice.org/2001/registry" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
 xml:lang='en-US'>
  <import oor:component="org.openoffice.Office.Common"/>
  <templates>
    <group oor:name="DataSettings">
      <prop oor:name="Filter" oor:type="xs:string">
        <value/>
      </prop>
      <prop oor:name="ApplyFilter" oor:type="xs:boolean">
        <value>false</value>
      </prop>
      <prop oor:name="Order" oor:type="xs:string">
        <value/>
      </prop>
      <prop oor:name="RowHeight" oor:type="xs:int"/>
      <prop oor:name="TextColor" oor:type="xs:int"/>
      <prop oor:name="TextLineColor" oor:type="xs:int"/>
      <prop oor:name="CharacterEmphasis" oor:type="xs:short"/>
      <prop oor:name="CharacterRelief" oor:type="xs:short"/>
      <node-ref oor:name="Font" oor:node-type="Font" 
                                    oor:component="org.openoffice.Office.Common"/>
    </group>
   ...
  </templates>
  <component>
    ...
  </component>
</oor:component-schema>

The DataAccess component schema contains entries for storing UI data, including information about fonts. Font settings are stored for several components within OpenOffice.org. For this reason, a common component schema 'org.openoffice.Office.Common' provides a template definition 'Font' for font settings. The DataAccess component schema prepares using this template by specifying the <import> tag pointing to the 'org.openoffice.Office.Common' component schema. The 'DataSettings' group-node template contains a reference to the 'Font' template in the imported component. A template reference (in a set, item or node-ref element) completely identifies the template by a combination of attributes: The component attributes identifies a imported component schema by its FQCN. The node-type attribute identifies the template within that component schema. If no component attribute is present, the template is looked up in the current component schema.

Localization of Properties

OOR provides the possibility of storing different property content for different locales. This is often useful, when configuration data contains items that are displayed by the user interface. A property must be marked as localized in the schema to enable support for content that varies with th locale. It is not possible to define localized default contents in the schema, which is considered to be language-neutral and is closed against extensions like adding new locales. (You can specify a language-neutral default value in the schema). Only the update format offers locale-specific content.

Update tree fragment with localized properties.

<?xml version="1.0" encoding="utf-8"?>
<oor:component-data oor:name="DataAccess" oor:package="org.openoffice.Office" 
 xsi:schemaLocation="http://openoffice.org/2001/registry/component-update.xsd" 
 xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:oor="http://openoffice.org/2001/registry" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">  
  <node oor:name="DriverSettings">
    <node oor:name="com.sun.star.comp.sdbc.mozaddressbook.Driver">
      <node oor:name="ColumnAliases">
        <prop oor:name="FirstName" oor:type="xs:string" oor:localized="true">
          <value xml:lang="de">Vorname</value>
          <value xml:lang="en-US">First Name</value>
        </prop>
        <prop oor:name="LastName" oor:type="xs:string" oor:localized="true">
          <value xml:lang="de">Nachname</value>
          <value xml:lang="en-US">Last Name</value>
        </prop>
        <prop oor:name="DisplayName" oor:type="xs:string" oor:localized="true">
          <value xml:lang="de">Anzeigename</value>
          <value xml:lang="en-US">Display Name</value>
        </prop>
        <prop oor:name="NickName" oor:type="xs:string" oor:localized="true">
          <value xml:lang="de">Spitzname</value>
          <value xml:lang="en-US">Nickname</value>
        </prop>
        <prop oor:name="PrimaryEmail" oor:type="xs:string" oor:localized="true">
          <value xml:lang="de">E-Mail</value>
          <value xml:lang="en-US">E-mail</value>
        </prop>
      </node>
    </node>
  </node>
</oor:component-data>

To associate specific value settings with a locale, the value element of a property has an xml:lang attribute whose value is the language to which this value applies. This provides the ability to distinguish the property content for certain locales. In the example above each property of the node 'ColumnAliases' has a localization for the locales 'de' and 'en-US', specified by the xml:lang attribute. It is up to the application, to select the correct value element for a property depending on some locale preferences. It can use, for example, the user's preferred locale, the locale of the operating system or even a prioritized list of accepted languages to select the appropriate content for a property. It also depends on the matching algorithm, which entry is actually selected. So, one way to select the appropriate value for a user could be:

Note: To illustrate the matching algorithm below, we consider that the user has a preferred locale 'en-US'.

  1. Find an exact match for the locale given for the user :
    The property must have a value with a xml:lang attribute value 'en-US'; otherwise,

  2. find an exact match for the language part of the locale:
    The property must have a value with a xml:lang attribute value 'en'; otherwise,

  3. find the first locale, that matches at least the language part:
    For the given locale 'en-US' this means, use a filter 'en-*'. If you find one or more matching entries, use the first one of the matching list; otherwise,

  4. take the language-neutral value
    There might be a language-neutral value for the property. This could be from one of the layers, but it could also be the default value that was specified in the component schema.If there is a language-neutral default use it; otherwise

  5. take the first localized value:
    If there are any localized values at all, take the first value out of the list of available locale values, or otherwise

  6. return a NIL value. As with non-localized values, this might be a constraint violation, if the property is not nillable.

The section 'Layering and Merging' will provide further information of how localized properties are treated in the merging process.

Extensible Nodes

There are certain situations where clients need to be able to extend the characteristics of a node during runtime. For example, generic service registries may need to allow storing arbitrary extra information for specific services, which are represented by configuration nodes. OOR provides the possibility of extending the list of properties for nodes, by declaring them as extensible in the component schema.

Declaration of extensible nodes in the 'DataAccess' component schema.

<?xml version="1.0" encoding="utf-8"?>
<oor:component-schema oor:name="DataAccess" oor:package="org.openoffice.Office" 
 xsi:schemaLocation="http://openoffice.org/2001/registry component-schema.xsd" 
 xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:oor="http://openoffice.org/2001/registry" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <templates>  
    ...
    <group oor:name="DataSourceDescription" oor:extensible="true">
      <prop oor:name="URL" oor:type="xs:string"/>
      <prop oor:name="IsPasswordRequired" oor:type="xs:boolean"><value>true</value></prop>
      <prop oor:name="TableFilter" oor:type="oor:string-list">
        <value oor:separator=";">%</value>
      </prop>
      <prop oor:name="TableTypeFilter" oor:type="oor:string-list"/>
      <prop oor:name="NumberFormatSettings" oor:type="xs:hexBinary"/>
      <prop oor:name="User" oor:type="xs:string"/>
      <prop oor:name="LoginTimeout" oor:type="xs:int"/>
      <prop oor:name="SuppressVersionColumns" oor:type="xs:boolean">
        <value>true</value>
      </prop>
      <prop oor:name="LayoutInformation" oor:type="xs:hexBinary"/>      
      <set oor:name="Tables" oor:node-type="Table"/>
      <set oor:name="Queries" oor:node-type="Query"/>
      <set oor:name="Bookmarks" oor:node-type="Bookmark"/>
    </group>    
    ...
  </templates>
  <component>
    ...
    <set oor:name="DataSources" oor:node-type="DataSourceDescription"/>
    ...
   </component>
</oor:component-schema>

If you look at the schema snippet given above, you will find the template-node 'DataSourceDescription'. This node is defined as extensible (oor:extensible = 'true'). In addition to settings that are common for all data-sources (like 'URL' or 'User') it offers the possibility to store data-source specific settings. The next example of a update tree contains a data-source definition called 'Bibliography' illustrating that feature.

Update tree with a single 'DataSource' definition

<?xml version="1.0" encoding="utf-8"?>
<oor:component-data oor:name="DataAccess" oor:package="org.openoffice.Office" 
 xsi:schemaLocation="http://openoffice.org/2001/registry component-update.xsd" 
 xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:oor="http://openoffice.org/2001/registry" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <node oor:name="DataSources">
    <node oor:name="Bibliography">
      <prop oor:name="URL">
        <value>sdbc:dbase:$(userurl)/database/biblio</value>
      </prop>
      <prop oor:name="IsPasswordRequired">
        <value>false</value>
      </prop>
      <prop oor:name="TableFilter">
        <value>%</value>
      </prop>
      <prop oor:name="LoginTimeout">
        <value>0</value>
      </prop>
      <prop oor:name="SuppressVersionColumns">
        <value>false</value>
      </prop>
      <prop oor:name="CharSet" oor:type="xs:string" op='replaced'>
        <value>IBM850</value>
      </prop>      
    </node>    
    ...
   </node>
</oor:component-data>

In addition to the common properties of 'DataSourceDescription', 'Bibliography' contains an additional property 'CharSet', which defines the character set used for the Bibliography database. This property is specific to that data-source instance.

Properties added to an extensible in layer can be removed at runtime in the layer where they were added. But properties that are specified by the schema are mandatory, which means that they cannot be removed. This holds for both extensible and non-extensible nodes. The section about layering and merging will provide further information about extensible nodes.

Property Constraints

In the above component schema for the 'DataAccess' component, constraints are not shown due to space constraints (no pun intended). But the facility to specify constraints in the schema can be helpful both to authors and readers of a schema and to programs manipulating configuration data. Constraints serve at least as supplementary documentation, but client programs SHOULD also be written to enforce them when updating OOR data. Constraints are not enforced via the XML schema, so constraint violations can't easily be prevented from appearing in a layer document. Thus robust client programs should be prepared to handle even data that violates the constraints.

A constraint on a property is an additional restriction on the basic data-type of the property. OOR knows the following constraint facets from the XML Schema Datatypes standard:

  • enumeration: limits the property to a number of distinct values. Not available for the xs:boolean data-types.

  • length: limits the length of an xs:string or an xs:hexBinary property value.

  • minLength, maxLength: limits the minimal and maximal length of a property value. Only applied for xs:string and xs:hexBinary data-types.

  • minInclusive, maxInclusive: defines a range for numeric data-types, values for minInclusive and maxInclusive are within the range.

  • minExclusive, maxExclusive: defines a range for numeric data-types, values for minExclusive and maxExclusive are outside the range.

  • whiteSpace: defines the way whitespace is treated for string and binary content. Actually, this is more a conversion rule than a validation rule. The default value is 'preserve'. Otherwise possible values are 'replace' or 'collapse'.

All the constraints are well known in XMLSchema. Find more information about the meaning of each constraint in XML Schema Part 2: Datatypes.
The table below contains a matrix indicating which constraint can be applied on what data-type.

constraint/
data-type

enumeration

length

minLength/
maxLength

minInclusive/
maxInclusive

minExclusive/
maxExclusive

whiteSpace

xs:string

x

x

x

 

 

x

xs:hexBinary

x

x

x

 

 

x

xs:boolean

 

 

 

 

 

 

xs:short

x

 

 

x

x

 

xs:int

x

 

 

x

x

 

xs:long

x

 

 

x

x

 

xs:double

x

 

 

x

x

 

All list data-types can not be constrainted. This is only possible for the primitives, except boolean, which is itself an enumeration. Here are some examples for constraints, which also exhibit the other documentation facilities of the Schema Document Format:


Enumeration examples 'FormSearchOptions' from 'DataAccess'

<?xml version="1.0" encoding="utf-8"?>
<oor:component-schema oor:name="DataAccess" oor:package="org.openoffice.Office" 
 xsi:schemaLocation="http://openoffice.org/2001/registry component-schema.xsd" 
 xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:oor="http://openoffice.org/2001/registry" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <templates>  
    ...
  </templates>
  <component>
    ...
    <group oor:name="FormSearchOptions">
      <prop oor:name="SearchType" oor:type="xs:string">
        <info>
          <desc xml:lang="en-US">Specifies the search type.</desc>
        </info>
        <constraints>
          <enumeration oor:value="text">
            <info>
              <desc xml:lang="en-US">A text value should be searched for.</desc>
            </info>
          </enumeration>
          <enumeration oor:value="null">
            <info>
              <desc xml:lang="en-US">A NULL value should be searched for.</desc>
            </info>
          </enumeration>
          <enumeration oor:value="non-null">
            <info>
              <desc xml:lang="en-US">A non-NULL value should be searched for.</desc>
            </info>
          </enumeration>
        </constraints>
        <value>text</value>
      </prop>
      <prop oor:name="SearchPosition" oor:type="xs:string">
        <info>
          <desc xml:lang="en-US">Specifies the search position.</desc>
        </info>
        <constraints>
          <enumeration oor:value="anywhere-in-field">
            <info>
              <desc xml:lang="en-US">Specifies that the searched value can be anywhere in the field.</desc>
            </info>
          </enumeration>
          <enumeration oor:value="beginning-of-field">
            <info>
              <desc xml:lang="en-US">Specifies that the searched value must be at the beginning of the field.</desc>
            </info>
          </enumeration>
          <enumeration oor:value="end-of-field">
            <info>
              <desc xml:lang="en-US">Specifies that the searched value must be at the end of the field.</desc>
            </info>
          </enumeration>
          <enumeration oor:value="complete-field">
            <info>
              <desc xml:lang="en-US">Specifies that the searched value must be the complete field.</desc>
            </info>
          </enumeration>
         </constraints>
         <value>anywhere-in-field</value>
      </prop>
    <group/
  </component>
</oor:component-schema>
The 'SearchType' and 'SearchPosition' properties are restricted to a lists of discrete values describing certain characteristics of a search. The properties have default values which assume one of the enumerated values.


Range Example 'History' from 'Common'

...
<oor:group oor:name="History">
  <prop oor:name="Size" oor:type="xs:int">
     <info>
       <desc xml:lang="en-US">List size of recently opened documents.</desc>
       <label xml:lang="en-US">Size</label>
     </info>    
     <constraints>
       <minInclusive oor:value="0"/>
       <maxInclusive oor:value="100"/>
     </constraints>
     <value>100</value>
   </prop>
   <prop oor:name="PickListSize" oor:type="xs:int">
     <info>
       <deprecated>since version 0.9</deprecated>
       <author>Dirk Grobler</author>
       <author>Joerg Barfurth</author>
       <desc xml:lang="en-US">Max. number of displayed picklist menu items.</desc>
       <label xml:lang="en-US">Menu Picklist Size</label>
     </info>
     <constraints>
       <minInclusive oor:value="0"/>
       <maxInclusive oor:value="9"/>
     </constraints>
     <value>4</value>
   </prop>
</oor:group>
The OpenOffice.org application provides a history for recently open documents. The history is limited to a configurable size. This Size limit is restricted to a minimum of zero documents (no history) and a maximum of 100 documents, which is the default. There also is a list of recent documents shown in the File menu. The number of items to be shown can be limited to a number in the range 0..9, with a default of 4 documents.

Annotations

Within the component schema, it is possible to add information for documentation purposes. This is done using the <info> tag, which is allowed as an (optional) child element for all component schema xml elements. The info element contains up to four child elements. The <deprecated> marks an element that is kept only for backward compatibility. It SHOULD contain a string that indicates the version from which on the entry is obsolete. Using one or more <author> elements the original author or multiple contributors and maintainers can be named. The contents of this element SHOULD be the name of a person. The <desc> element SHOULD contain a human-readable description of the annotated element, that explains the possible values and their meaning and is suitable for use as a help text for understanding and manipulating the data. Lastly a <label> element SHOULD provide a short human-readable title for a schema element.

Annotations are useful for application developers that want to use the configuration data in their application. But they should also be usable for generic registry viewing and editing tools that present the configuration data to the user or administrator in a meaningful way. Typically such tools will show the <label> content as as name or label of the element and will present the <desc> content as explanatory text. It is recommended to add the xml:lang attribute to the documentation and label element to indicate the language of the information. An alternative is to provide the language attribute at the root element of the component schema, to indicate that the same language is used for all information items. The previous examples exhibited various uses of annotaion elements.

Versioning

Like applications the configuration schemas may evolve over time and different versions of a schema are created. To identify the versions of configuration schemas and to support an update process, which migrates configuration data from an older to a newer version, the configuration schema should contain versioning information .

The OOR format has a basic support for schema versioning. Each component schema can provide a version attribute. It is recommended to use a version numbering scheme where a version identifier has the form 'major.minor.micro', where

  • Major version numbers identify significant (possibly incompatible) changes of the component schema.
  • Minor version numbers identify less significant (compatible) extensions to the component schema.
  • Micro versions indicate semantically insignificant modifications like changing default values or changing informational items.

[This section may be augmented greatly in the future, when an overarching framework for tagging and handling schema versions is developed.]

Advanced Concepts

This chapter explains more sophisticated concepts of OOR, like layering, merging and access control for nodes. Their description gives you a deeper understanding of the capabilities of the registry format.
These concepts are important for deployment and administration of a multi-layered configuration registry, but typically, they are not directly visible at the API of a registry access library. Thus if you only need to define a component configuration schema and use it from your application, you can skip this chapter. Only if you are implementing your own registry access library will you need to read all of it.

Layering and Merging

To reduce the size of configuration data stored for a single user and to enable certain administrability features, OOR provides a mechanism to layer configuration settings and to store in each layer only differences compared to a default tree. A natural default layer within OOR is the schema layer. A component schema provides a default configuration tree for a single component which includes default settings for some properties. This tree is considered read-only, as the schema itself is immutable. Any changes compared to this default have to be placed into another layer. When fetching the configuration data on behalf of an application, both layers are read and merged before the data is offered to the client.

It is also possible and common to use more than two layers. In this case the merge algorithm is applied repeatedly. For example you can have three layers A, B and C, where A is the schema layer, B adds additional settings for a group of users and C holds data for a specific user. In this case B contains only the differences compared to A and C contains only the differences compared to A merged with B. In other words A provides the default tree for B and this tree merged with B serves as default tree for C.

Only the schema layer, which provides the original default tree employs the OOR Schema Document Format. All other layers contain differences and use the OOR Update Document Format. Differences are represented in the update format as operations to be executed on the elements of the configuration tree during the merge process. There are four operations, as follows:

  • Operation 'modify':
    'Modify'
    is the default operation. Therefore the op attribute for this operation can be omitted in the update format. It indicates that the current node or property contains modifications to be applied to the corresponding node in the default tree. Possible modifications are changing an attribute (e.g. regarding access control) of the element, changing the value of a property or applying modification to sub-nodes. The modify operation can be applied to all kinds of elements of the configuration tree. A prerequisite for the operation is, that the element to be modified exists in the default layer; otherwise the modification is invalid and the whole node is ignored. In other words this operation actually combines the content of a base node in the default tree with the content of the modification node in the update layer representing a true merge.

  • Operation 'replace':
    This operation can only be applied to dynamic elements, i.e. sub-nodes of a set or dynamic properties added to extensible nodes. It indicates that a corresponding element from the default tree, if present, should be ignored. Instead the element should be constructed as if the current layer were the first after the schema. Thus replace nodes are only combined with settings from the component schema. A replaced node in a set is based on a template and contains only modifications relative to the default tree fragment created from the template. During the merge process a corresponding node in the default tree is discarded, a new tree is created from the template and the contents of the update node is applied to this clean tree.

    The replace operation does not require that a corresponding node to be replaced is available. It also must be used to add a new node to a set or extensible node. Thus the real meaning of the operation is “add or replace”. Dynamic properties can only be added once and are then considered mandatory, so during layer merging the replace operation always means “add” for them,

  • Operation ‘fuse’ (introduced in OOo 2.0.2):
    This operation has a meaning of “modify or replace.” It has the same effect as modify (“merge with existing data”) if the element already exists, but it has the effect of replace (“add, possibly based on template”) if the element does not yet exist.

  • Operation 'remove':
    Like the 'replace' operation, 'remove' can only be applied to sub-nodes of a set. If there is a corresponding element in the default tree it is hidden and does not appear in the merge result tree. It is not possible to hide dynamic properties that were added to an extensible node in another layer. But in update documents that are not layers, but describe an update to an existing layer, the operation can also be applied todynamic properties that were added in the layer being updated.

  • Operation 'reset':
    All operations mentioned so far, can be used either for specifying an update on a particular layer or to describe the rules for combining data during the layer merge process. 'Reset' is meaningful only for the updates. It means 'reset a fragment of the configuration tree back to its default'. To achive this the corresponding node is physically deleted from the target layer, so the corresponding fragment of the default tree will be unchanged by merging this layer.

    A 'reset' operation can also be combined with subsequent change operations. In this case the affected element and children are removed from the layer and replaced with the set of operations nested in the 'reset' operation (but with operation 'modify'). If a 'reset' operation is encountered in a layer document being merged, it has the same effect as 'modify'.

For future evolution an extension to the list of existing operations is considered:

  • Operation 'clear':
    This operation differs from 'replace','remove' and 'fuse' in that it is not applied to dynamic elements themselves, but to containers of dynamic elements. The effect is to remove/hide all contained elements that are not mandatory. Thus, unless an element has been marked as mandatory in the default tree, a set is restartde empty and only the elements added in the current layer are visible.

Merging update layers

OOR allows to merge two update layers A and B without taking into account the data (and especially the schema) D with which the two update layers shall ultimately be merged. Generally, the result of first merging A and B in this way into a new update layer and then merging D with that new update layer, and the result of first merging D with A and then merging the result with B (i.e., the usual way of merging) should be identical. There is one problematic case where the results are not identical, however (see below).

The following table describes how both nodes and properties are merged when merging two update layers A and B (in OOo, which only supports the operations modify, replace, fuse, and remove for nodes, and only supports the operations modify and replace for properties):

B
modify replace fuse remove
A modify B replace B fuse B remove
modify modify A modify A+B replace B fuse A+B* remove
replace replace A replace A+B replace B replace A+B remove
fuse fuse A fuse A+B replace B fuse A+B remove
remove remove remove replace B fuse B remove

The problematic case (marked with a “*”) is a modify from A followed by a fuse from B: Depending on the data D with which the combined update will be merged, the modifications from A could get lost (if the given node is not present in D) when merging in the usual way (first merge D with A, then merge the result with B). However, when first merging A and B, the modifications from A do not get lost in this way, even if the given node is not present in D.

Localized properties

Localized properties may contain a list of values, where each value is specified for a certain locale by the xml:lang attribute (see also Localization of Properties). If a property is modified in a writeable layer by changing a value for a certain locale, it overrides the locale specific value of the default layer. Other locale specific property values are not affected by the overwritten value. They are still visible in the writeable layer and can be considered during the value selection process (see also locale selection). Thus you can add new locales to an existing property without repeating all existing localization in the same layer.

The 'clear' operation could also be supported on localized properties to indicate, that all localizations from previous layers should be discarded; this would be appropriate, when a change is not intended to add or change one localization, but to change the meaning of the property.

Omitting static information

Some information items allowed by the OOR format can be redundant. The corresponding attributes are optional. It may depend on the actual schema or on data from preceding layers whether an omission is possible. It is recommended, that such information is in fact omitted where it can be determined that this is safely possible. If redundant data is not omitted, processors should treat it as an error, if the given value is not consistent with the implied one. Below, you find a list of these optional information items:

  • oor:type: data-type of a property. This is optional in the update layer, unless it is a dynamic property or the schema specifies type any. In those cases, the attribute is required, if the <prop> contains a non-NIL value.

  • oor:node-type: identifies the template that is used for a set item or node-reference. This SHOULD be omitted in the update format, if the operation for this set item is not 'replace' (or 'fuse'). It can be omitted even for newly added set items, if the default template of the set should be used.

  • oor:component: identifies the component, a referenced template belongs to. Must not be specified, if no node-type attribute is present. Can be omitted, even in the schema, if the component is the current component. Must be specified, if a node-type is present and the template does not belong to the current component.

The following attributes can be specified only on schema elements. For nodes in a layer the applicable value can be found only by reference to the underlying schema.

  • oor:localized: determines, whether a property can be localized or not.

  • oor:nillable: specifies, if a property allows a NIL value or not.

  • oor:extensible: determines, if a node can have dynamic properties or not.

A merging example

This example contains a sequence of merging steps. All merging steps are based on the reduced component schema given below, which contains settings for the 'DriverManager' and the 'ConnectionPool' node.

Component schema providing defaults for 'DriverManager' and 'ConnectionPool'

<?xml version="1.0" encoding="utf-8"?>
<oor:component-schema oor:name="DataAccess" oor:package="org.openoffice.Office" 
 xsi:schemaLocation="http://openoffice.org/2001/registry component-schema.xsd" 
 xmlns:xs="http://www.w3.org/2001/XMLSchema" 
 xmlns:oor="http://openoffice.org/2001/registry" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xml:lang='en-US'>
  <templates>  
    <group oor:name="DriverPooling">      
      <prop oor:name="Enable" oor:type="xs:boolean">
        <value>true</value>
      </prop>
      <prop oor:name="Timeout" oor:type="xs:int"/>
    </group>
  </templates>
  <component>
    <group oor:name="DriverManager">
      <prop oor:name="DriverPrecedence" oor:type="oor:string-list">
        <value oor:separator=";">com.sun.star.comp.sdbc.ODBCDriver;
com.sun.star.comp.sdbc.JDBCDriver</value>
      </prop>
    </group>
    <group oor:name="ConnectionPool">
      <prop oor:name="EnablePooling" oor:type="xs:boolean">
        <value>true</value>
      </prop>
      <set oor:name="DriverSettings" oor:node-type="DriverPooling"/>
    </group>  
   </component>
</oor:component-schema> 

The component schema acts as the default layer for the following merging steps. Each step will use the merge result of the previous step and apply additional changes. Each step contains, therefore, two fragments. The first part is the update layer containing the differences and the second part is the result of applying the differences on the previous merge result. The merge result is specified in a fictitious 'Merged format', which is used for illustration purposes. There is actually no such format in OOR. Typically an application uses an internal representation of the merge result.

Modified nodes

The first step describes the simplest way of modification, a change of a single preference setting. The difference fragment contains the modification of the 'DriverPrecedence' for the 'DriverManager'. It actually changes the precedence of drivers.

Fragment containing a modification for 'DriverPrecedences'

<?xml version="1.0" encoding="utf-8"?>
<oor:component-data oor:name="DataAccess" oor:package="org.openoffice.Office">
  <node oor:name="DriverManager">
    <prop oor:name="DriverPrecedence" oor:op='modify'>
<value oor:separator=";">com.sun.star.comp.sdbc.JDBCDriver;
com.sun.star.comp.sdbc.ODBCDriver</value>
    </prop>
  </node>
</oor:component-data> 

Result tree

<?xml version="1.0" encoding="utf-8"?>
<oor:component oor:name="DataAccess" oor:package="org.openoffice.Office">
  <group oor:name="DriverManager">
    <prop oor:name="DriverPrecedence">
<value oor:separator=";">com.sun.star.comp.sdbc.JDBCDriver;
com.sun.star.comp.sdbc.ODBCDriver</value>
    </prop>
  </group>
  <group oor:name="ConnectionPool">
     <prop oor:name="EnablePooling">
       <value>true</value>
     </prop>
     <set oor:name="DriverSettings"/>
  </group>  
</oor:component>

The result tree contains the changed driver precedence. All other nodes of the component schema are still untouched and are for this reason visible in the result tree.

Note: The modify operation can be omitted in the update format, as this is the default operation for elements. This is actually done for the surrounding nodes 'DataAccess' and 'DriverManager'.

Note: Both, the fragment and the result tree do not contain information like property data types or set item types, that can be recovered by reference to the component schema.

Inserted nodes

The next step involves the set-node 'DriverSettings' of the connection pooling entry. It introduces two additional nodes of type 'DriverPooling'.

Component fragment containing new 'ConnectionPool' entries

<?xml version="1.0" encoding="utf-8"?>
<oor:component-data oor:name="DataAccess" oor:package="org.openoffice.Office">
  <node oor:name="ConnectionPool">
    <node oor:name="DriverSettings">
      <node oor:name="com.sun.star.comp.sdbcx.adabas.ODriver" oor:op="replace">
        <prop oor:name="Timeout">
          <value>60</value>
        </prop>
      </node>      
      <node oor:name="com.sun.star.comp.sdbc.ODBCDriver" oor:op="replace">
        <prop oor:name="Timeout">
          <value>60</value>
        </prop>
      </node>      
    </node>
  </node>    
</oor:component-data> 

Result tree

<?xml version="1.0" encoding="utf-8"?>
<oor:component oor:name="DataAccess" oor:package="org.openoffice.Office">
  <group oor:name="DriverManager">
    <prop oor:name="DriverPrecedence" oor:type="oor:string-list">
      <value oor:separator=";">com.sun.star.comp.sdbc.JDBCDriver;
com.sun.star.comp.sdbc.ODBCDriver</value>
    </prop>
  </group>
  <group oor:name="ConnectionPool">
     <prop oor:name="EnablePooling">
       <value>true</value>
     </prop>
     <set oor:name="DriverSettings">
       <group oor:name="com.sun.star.comp.sdbcx.adabas.ODriver">
         <prop oor:name="Enable">
           <value>true</value>
         </prop>
         <prop oor:name="Timeout">
           <value>60</value>
        </prop>
       </group>       
       <group oor:name="com.sun.star.comp.sdbc.ODBCDriver">
         <prop oor:name="Enable">
           <value>true</value>
         </prop>
         <prop oor:name="Timeout">
           <value>60</value>
        </prop>
       </group>
    </set>
  </group>  
</oor:component>

The fragment adds two new nodes into the set-node 'DriverSettings'. Both are available from the node-type 'DriverPooling', which is a template specified in the component schema. The fragment does not fully populate the two new nodes. Only one property 'Timeout' appears with the value 60. The other property 'Enable' isn't overridden and therefore doesn't appear in the layer. The value is inherited from the template definition during the merging process.

Removed nodes

The removal of nodes can happen in two ways depending on the layer, where the nodes are introduced. If the node does belong to a default layer, the node will be marked by a 'remove' operation and the merging process will ignore this node. If the node was introduced on the same layer, it can simply be deleted from the layer without flagging the node. There is only one drawback for the second procedure. The node might reappear after removal in the merging process. This happens when a node with the same access path exists in the default layer. In this case, the marking of the node with a 'remove' operation is preferred. In the merged tree. the removed node is simply not present.

Fragment containing the removal information for an existing node of the default layer.

<?xml version="1.0" encoding="utf-8"?>
<oor:component-data oor:name="DataAccess" oor:package="org.openoffice.Office">
  <node oor:name="ConnectionPool">
    <node oor:name="DriverSettings">
      <group oor:name="com.sun.star.comp.sdbcx.adabas.ODriver" oor:op="remove"/>
    </node>
  </node>    
</oor:component-data> 

Result tree

<?xml version="1.0" encoding="utf-8"?>
<oor:component oor:name="DataAccess" oor:package="org.openoffice.Office">
  <group oor:name="DriverManager">
    <prop oor:name="DriverPrecedence" oor:type="oor:string-list">
<value oor:separator=";">com.sun.star.comp.sdbc.JDBCDriver;
com.sun.star.comp.sdbc.ODBCDriver</value>
    </prop>
  </group>
  <group oor:name="ConnectionPool">
     <prop oor:name="EnablePooling">
       <value>true</value>
     </prop>
     <set oor:name="DriverSettings">            
       <group oor:name="com.sun.star.comp.sdbc.ODBCDriver">
         <prop oor:name="Enable">
           <value>true</value>
         </prop>
         <prop oor:name="Timeout">
           <value>60</value>
         </prop>
       </group>       
    </set>
  </group>  
</oor:component>

Replaced nodes

Replacing nodes is pretty much the same as adding a new node. Both the added and the replaced node are introduced by the 'replace' operation. A replace operation hides nodes with the identical access path and replaces them completely. In the example below, the settings for the odbc driver have been replaced. It now disables pooling. The replaced entry enabled connection pooling and specified a timeout. As the node is replaced, the changes in the default layer are ignored. Thus the timeout set in the default layer is not visble in the merged tree.This would be different, if the node were modified rather than replaced. To highlight this fact, the NIL default from the schema is explicitly expanded in the result tree below.

Fragment containing a replacement within 'DriverPrecedences'
<?xml version="1.0" encoding="utf-8"?>
<oor:component-data oor:name="DataAccess" oor:package="org.openoffice.Office">
  <node oor:name="ConnectionPool">
    <node oor:name="DriverSettings">
       <node oor:name="com.sun.star.comp.sdbc.ODBCDriver" oor:op='replace'>
         <prop oor:name="Enable">
           <value>false</value>
         </prop>
       </node>       
    </node>
  </node>    
</oor:component-data> 

Result tree

<?xml version="1.0" encoding="utf-8"?>
<oor:component oor:name="DataAccess" oor:package="org.openoffice.Office">
  <group oor:name="DriverManager">
    <prop oor:name="DriverPrecedence">
      <value oor:separator=";">com.sun.star.comp.sdbc.JDBCDriver;
com.sun.star.comp.sdbc.ODBCDriver</value>
    </prop>
  </group>
  <group oor:name="ConnectionPool">
     <prop oor:name="EnablePooling">
       <value>true</value>
     </prop>
     <set oor:name="DriverSettings">            
       <group oor:name="com.sun.star.comp.sdbc.ODBCDriver">
         <prop oor:name="Enable">
           <value>true</value>
         </prop>
         <prop oor:name="Timeout">
           <value xsi:nil=”true” />
         </prop>
       </group>
    </set>
  </group>  
</oor:component>

Access Control

OOR provides a simple mechanism for access control, which makes use of the layering concept. By default, each node and property can be modified or extended depending on the semantics of the node. A group-node allows altering its children and changing properties; a set-node allows to add new items and to modify,replace or remove existing items. A property allows changing its value(s).

In 'default' layers, which may apply to user-groups or the entire installation, it may be desirable to restrict the possibility of overriding nodes and their properties in a subsequent layer. To this end it is possible to finalize a node. Finalizing a node always effects the node itself, its properties, its children and all its descendent nodes recursively. It is not possible to selectively change a subset of a finalized subtree back to overrideable. A finalized node is considered to be read-only for all subsequent layers. Changes to that node and children in subsequent layers are not permitted and are ignored during the merge process.

Below, you find an example which illustrates the meaning of finalizing a node. If you think of the two layers involved in the merging process as a user-group and a user, a group administrator might decide to finalize the node 'DriverSettings'. In this case, the group administrator can still apply changes to that node, but users, which are members of that user-group can't change that node or any of its sub-nodes. Therefore, the node 'DriverSettings' is marked as read-only, when the configuration data is retrieved on behalf of the user as shown in the merged tree. read-only is a computed state, which results out of the evaluation of the finalize flag during the merge process. For clarity, the read-only state is here shown on all nodes to which it applies.

Fragment for a group with a finalized node

<?xml version="1.0" encoding="utf-8"?>
<oor:component-data oor:name="DataAccess" oor:package="org.openoffice.Office">
  <node oor:name="ConnectionPool">
    <node oor:name="DriverSettings" oor:finalized="true">
      <node oor:name="com.sun.star.comp.sdbc.ODBCDriver" oor:op='replace'>
         <prop oor:name="Enable">
           <value>true</value>
         </prop>
         <prop oor:name="Timeout">
           <value>600</value>
         </prop>
      </node>       
    </node>
  </node>    
</oor:component-data> 

Result tree for a user, who is member of the user-group

<?xml version="1.0" encoding="utf-8"?>
<oor:component oor:name="DataAccess" oor:package="org.openoffice.Office">
  <group oor:name="DriverManager">
    <prop oor:name="DriverPrecedence">
      <value oor:separator=";">com.sun.star.comp.sdbc.JDBCDriver;
com.sun.star.comp.sdbc.ODBCDriver</value>
    </prop>
  </group>
  <group oor:name="ConnectionPool">
     <prop oor:name="EnablePooling" oor:type="xs:boolean">
       <value>true</value>
     </prop>
     <set oor:name="DriverSettings" oor:readonly="true">
       <group oor:name="com.sun.star.comp.sdbc.ODBCDriver" oor:readonly="true" >
         <prop oor:name="Enable" oor:readonly="true">
           <value>true</value>
         </prop>
         <prop oor:name="Timeout" oor:readonly="true">
           <value>600</value>
         </prop>
       </group>
    </set>
  </group>  
</oor:component>
Another way to restrict the access of nodes is to declare items of a set as mandatory. Mandatory items must be present in the merged tree and cannot be removed or replaced in subsequent layers. By declaring an item as mandatory, the item gets the same characteristics as a member of a group-node and acts as static element in the component hierarchy. Dynamic properties , added to an extensible node, are always treated as mandatory. The closest approximation to removing a dynamic attribute is by setting its value to NIL.


Fragment for a group with a mandatory node

<?xml version="1.0" encoding="utf-8"?>
<oor:component-data oor:name="DataAccess" oor:package="org.openoffice.Office">
  <node oor:name="ConnectionPool">
    <node oor:name="DriverSettings">
      <node oor:name="com.sun.star.comp.sdbc.ODBCDriver" oor:mandatory="true">
         <prop oor:name="Timeout">
           <value>600</value>
         </prop>         
       </node>
    </node>
  </node>    
</oor:component-data> 


Appendix A - Registry Component Types

This is the basic schema of the OOR format. It is included for all sub-formats of OOR.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://openoffice.org/2001/registry" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:oor="http://openoffice.org/2001/registry" 
    elementFormDefault="unqualified" attributeFormDefault="qualified">
  <xs:annotation>
    <xs:documentation>provides a list of standard attribute and element definitions, 
              reused in most parts of the different OOR document types</xs:documentation>
  </xs:annotation>
  <xs:import namespace="http://www.w3.org/XML/1998/namespace" 
             schemaLocation="http://www.w3.org/2001/xml.xsd"/>
  <!--List of attributes known in OOR-->
  <xs:attribute name="name" type="xs:string" use="required">
    <xs:annotation>
      <xs:documentation>identifies a node or an attribute within a tree, 
                must be unique for all siblings.</xs:documentation>
    </xs:annotation>
  </xs:attribute>
  <xs:attribute name="package" type="xs:NMTOKEN" use="required">
    <xs:annotation>
      <xs:documentation>contains the name of the package. 
                Package names are composed similar to java packages. 
                Packages are used to structure component configuration data. 
                An example of a package is 'org.openoffice', 
                where 'org' and 'openoffice' each define a package.</xs:documentation>
    </xs:annotation>
  </xs:attribute>
  <xs:attribute name="node-type" type="xs:NMTOKEN">
    <xs:annotation>
      <xs:documentation>identifies the template to use for the set or a node reference. 
      </xs:documentation>
    </xs:annotation>
  </xs:attribute>
  <xs:attribute name="component" type="xs:string" use="optional">
    <xs:annotation>
      <xs:documentation>specifies the component, which contains a template definition
      </xs:documentation>
    </xs:annotation>
  </xs:attribute>
 <xs:attribute name="separator" type="xs:string" default=" ">
    <xs:annotation>
      <xs:documentation>specifies a separator for list types. The default
                        is a blank, which is sufficient for most basic types like xs:int or
                        xs:boolean. Only in certain cases, when using a sting or a binary
                        list, the separator might differ. 
                            For example, a list of string values like build of the items 'europe' 
                            and 'south america' needs a different separator, as the usage of 
                            the default separator would result in a list of three items.
      </xs:documentation>
    </xs:annotation>
  </xs:attribute>
 <xs:attribute name="type" use="optional">
    <xs:annotation>
      <xs:documentation>specifies the list of known basic types and their list equivalents. 
                Is only allowed for properties.</xs:documentation>
    </xs:annotation>
    <xs:simpleType>
      <xs:restriction base="xs:string">
        <xs:enumeration value="xs:boolean"/>
        <xs:enumeration value="xs:short"/>
        <xs:enumeration value="xs:int"/>
        <xs:enumeration value="xs:long"/>
        <xs:enumeration value="xs:double"/>
        <xs:enumeration value="xs:string"/>
        <xs:enumeration value="xs:hexBinary"/>
        <xs:enumeration value="oor:any"/>
        <xs:enumeration value="oor:boolean-list"/>
        <xs:enumeration value="oor:short-list"/>
        <xs:enumeration value="oor:int-list"/>
        <xs:enumeration value="oor:long-list"/>
        <xs:enumeration value="oor:double-list"/>
        <xs:enumeration value="oor:string-list"/>
        <xs:enumeration value="oor:hexBinary-list"/>
      </xs:restriction>
    </xs:simpleType>
  </xs:attribute>
  <xs:attributeGroup name="node-info">
    <xs:annotation>
      <xs:documentation>encompasses common attributes for nodes.</xs:documentation>
    </xs:annotation>
    <xs:attribute ref="oor:name" use="required"/>
  </xs:attributeGroup>
  <xs:attributeGroup name="node-type-info">
    <xs:annotation>
      <xs:documentation>encompasses attributes for referencing a node-type.</xs:documentation>
    </xs:annotation>
    <xs:attribute ref="oor:node-type" use="required"/>
    <xs:attribute ref="oor:component" use="optional"/>
  </xs:attributeGroup>
  <xs:attributeGroup name="prop-info">
    <xs:annotation>
      <xs:documentation>encompasses common attributes for properties.</xs:documentation>
    </xs:annotation>
    <xs:attribute ref="oor:name" use="required"/>
  </xs:attributeGroup>
  <!--List of list data types supported by OOR-->
  <xs:simpleType name="boolean-list">
    <xs:list itemType="xs:boolean"/>
  </xs:simpleType>
  <xs:simpleType name="short-list">
    <xs:list itemType="xs:short"/>
  </xs:simpleType>
  <xs:simpleType name="int-list">
    <xs:list itemType="xs:int"/>
  </xs:simpleType>
  <xs:simpleType name="long-list">
    <xs:list itemType="xs:long"/>
  </xs:simpleType>
  <xs:simpleType name="double-list">
    <xs:list itemType="xs:double"/>
  </xs:simpleType>
  <xs:simpleType name="string-list">
    <xs:restriction base="xs:string"/>
  </xs:simpleType>
  <xs:simpleType name="hexBinary-list">
    <xs:restriction base="xs:string"/>
  </xs:simpleType>
  <!--List of basic type definitions for all schema and instance elements known by OOR-->
  <xs:complexType name="basic-node">
    <xs:annotation>
      <xs:documentation>base class for all kinds of nodes (set | group)</xs:documentation>
    </xs:annotation>
    <xs:attributeGroup ref="oor:node-info"/>
  </xs:complexType>
  <xs:complexType name="basic-prop">
    <xs:annotation>
      <xs:documentation>base type definition for properties</xs:documentation>
    </xs:annotation>
    <xs:attributeGroup ref="oor:prop-info"/>
  </xs:complexType>
  <xs:complexType name="value">
    <xs:annotation>
      <xs:documentation>type definition for values.</xs:documentation>
    </xs:annotation>
    <xs:simpleContent>
      <xs:extension base="oor:anyValue">
        <xs:attribute ref="oor:separator" use="optional"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
  <xs:simpleType name="anyValue">
    <xs:annotation>
      <xs:documentation>defines the list of possible basic data-types for properties.
      </xs:documentation>
    </xs:annotation>
    <xs:union memberTypes="xs:boolean xs:short xs:int xs:long xs:double xs:string xs:hexBinary 
                           oor:boolean-list oor:short-list oor:int-list oor:long-list 
                           oor:double-list oor:string-list oor:hexBinary-list"/>
  </xs:simpleType>
</xs:schema>



Appendix B - Registry Component Schema Format (component-schema.xsd)


<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://openoffice.org/2001/registry" 
    xmlns:oor="http://openoffice.org/2001/registry" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    elementFormDefault="unqualified" attributeFormDefault="qualified">
  <xs:annotation>
    <xs:documentation>specifies the document format for OOo configuration component schemata.
    </xs:documentation>
  </xs:annotation>
  <xs:attribute name="extensible" type="xs:boolean" use="optional" default="false">
    <xs:annotation>
      <xs:documentation>determines, whether a node has an extensible list of attributes or 
                fixed list of attributes.</xs:documentation>
    </xs:annotation>
  </xs:attribute>
  <xs:attribute name="localized" type="xs:boolean" use="optional" default="false">
    <xs:annotation>
      <xs:documentation>specifies, whether an attribute has or might have different values 
                for different locales. </xs:documentation>
    </xs:annotation>
  </xs:attribute>
  <xs:attribute name="nillable" type="xs:boolean" use="optional" default="true">
    <xs:annotation>
      <xs:documentation>specifies, whether it is permissible to have 'nil' 
          (i.e. missing) node content. 
          The default for 'nillable' is 'true'.
          If a non-optional (nillable = 'false') has no default value 
          (given in the component schema) 
          it must be explicitly specified for each user.
      </xs:documentation>
    </xs:annotation>
  </xs:attribute>
  <xs:complexType name="prop">
    <xs:annotation>
      <xs:documentation>redefines the property type 
              by adding documentation and type constraint elements.</xs:documentation>
    </xs:annotation>
    <xs:complexContent>
      <xs:extension base="oor:basic-prop">
        <xs:sequence>            
          <xs:element name="info" type="oor:info" minOccurs="0"/>
          <xs:element name="constraints" minOccurs="0">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="enumeration" type="oor:constraint" 
                            minOccurs="0" maxOccurs="unbounded"/>
                <xs:element name="length" type="oor:constraint" minOccurs="0"/>
                <xs:element name="minLength" type="oor:constraint" minOccurs="0"/>
                <xs:element name="maxLength" type="oor:constraint" minOccurs="0"/>
                <xs:element name="minInclusive" type="oor:constraint" minOccurs="0"/>
                <xs:element name="maxInclusive" type="oor:constraint" minOccurs="0"/>
                <xs:element name="minExclusive" type="oor:constraint" minOccurs="0"/>
                <xs:element name="maxExclusive" type="oor:constraint" minOccurs="0"/>
                <xs:element name="whiteSpace" type="oor:constraint" minOccurs="0"/>
              </xs:sequence>
            </xs:complexType>
          </xs:element>
          <xs:element name="value" type="oor:value" minOccurs="0"/>
        </xs:sequence>
        <xs:attribute ref="oor:localized"/>
        <xs:attribute ref="oor:nillable"/>
        <xs:attribute ref="oor:type" use="required"/>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:complexType name="group">
    <xs:annotation>
      <xs:documentation>type definition for group nodes</xs:documentation>
    </xs:annotation>
    <xs:complexContent>
      <xs:extension base="oor:basic-node">
        <xs:sequence>
          <xs:element name="info" type="oor:info" minOccurs="0"/>
          <xs:choice minOccurs="0" maxOccurs="unbounded">
            <xs:element name="prop" type="oor:prop"/>          
            <xs:element name="group" type="oor:group"/>
            <xs:element name="set" type="oor:set"/>
            <xs:element name="node-ref" type="oor:node-ref"/>
          </xs:choice>
        </xs:sequence>
        <xs:attribute ref="oor:extensible"/>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:complexType name="set">
    <xs:annotation>
      <xs:documentation>type definition for set nodes</xs:documentation>
    </xs:annotation>
    <xs:complexContent>
      <xs:extension base="oor:basic-node">
        <xs:sequence>
          <xs:element name="info" type="oor:info" minOccurs="0"/>
          <xs:element name="item" minOccurs="0" maxOccurs="unbounded">
            <xs:complexType>
              <xs:attributeGroup ref="oor:node-type-info" />
            </xs:complexType>
          </xs:element>
        </xs:sequence>
        <xs:attribute ref="oor:extensible"/>
        <xs:attributeGroup ref="oor:node-type-info" />
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:complexType name="node-ref">
    <xs:annotation>
      <xs:documentation>allows to define node references. 
          A node references points to an existing templated definition. 
          This definition will be expanded at runtime.
      </xs:documentation>
    </xs:annotation>
    <xs:sequence>
      <xs:element name="info" type="oor:info" minOccurs="0"/>
    </xs:sequence>
    <xs:attribute ref="oor:name" use="required"/>
    <xs:attributeGroup ref="oor:node-type-info" />
  </xs:complexType>
  <xs:complexType name="constraint">
    <xs:annotation>
      <xs:documentation>basic type for constraints, which can be applied for property elements.
      </xs:documentation>
    </xs:annotation>
    <xs:sequence>
      <xs:element name="info" type="oor:info" minOccurs="0"/>
    </xs:sequence>
    <xs:attribute name="value" type="xs:anySimpleType" use="required"/>
  </xs:complexType>
  <xs:complexType name="info">
    <xs:annotation>
      <xs:documentation>type for providing human readable information.  
          Can be attached to any kind of component schema element.
      </xs:documentation>
    </xs:annotation>
    <xs:sequence>
      <xs:element name="deprecated" type="xs:string" minOccurs="0">
        <xs:annotation>
          <xs:documentation>identifies an entry as deprecated. 
                    Can be associated with an explanation e.g. since when the entry is deprecated.
          </xs:documentation>
        </xs:annotation>
      </xs:element>
      <xs:element name="author" type="xs:string" minOccurs="0" maxOccurs="unbounded">
        <xs:annotation>
          <xs:documentation>author(s) of the configuration entry.</xs:documentation>
        </xs:annotation>
      </xs:element>
      <xs:element name="desc" minOccurs="0" maxOccurs="unbounded">
        <xs:complexType>
          <xs:annotation>
            <xs:documentation>provide a human
                        readable documentation for a schema element.</xs:documentation>
          </xs:annotation>
          <xs:simpleContent>
            <xs:extension base="xs:string">
              <xs:attribute ref="xml:lang"/>
            </xs:extension>
          </xs:simpleContent>
        </xs:complexType>
      </xs:element>
      <xs:element name="label" minOccurs="0" maxOccurs="unbounded">
        <xs:complexType>
          <xs:annotation>
            <xs:documentation>describes a title or label, which can be reused in a console.
            </xs:documentation>
          </xs:annotation>
          <xs:simpleContent>
            <xs:extension base="xs:string">
              <xs:attribute ref="xml:lang"/>
            </xs:extension>
          </xs:simpleContent>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>
  <xs:element name="component-schema">
    <xs:annotation>
      <xs:documentation>Root element, which encompasses the schema specification
      </xs:documentation>
    </xs:annotation>
    <xs:complexType>
      <xs:sequence>
        <xs:element name="info" type="oor:info" minOccurs="0"/>
        <xs:element name="import" minOccurs="0" maxOccurs="unbounded">
          <xs:complexType>
            <xs:attribute ref="oor:component" use="required"/>
          </xs:complexType>
        </xs:element>
        <xs:element name="uses" minOccurs="0" maxOccurs="unbounded">
          <xs:complexType>
            <xs:attribute ref="oor:component" use="required"/>
          </xs:complexType>
        </xs:element>
        <xs:element name="templates" minOccurs="0">
          <xs:complexType>
            <xs:sequence>
              <xs:choice minOccurs="0" maxOccurs="unbounded">
                <xs:element name="group" type="oor:group">
                  <xs:unique name="groupMember">
                    <xs:selector xpath="group|set|node-ref|prop"/>
                    <xs:field xpath="@oor:name"/>
                  </xs:unique>
                </xs:element>
                <xs:element name="set" type="oor:set"/>
              </xs:choice>
            </xs:sequence>
          </xs:complexType>
          <xs:unique name="templatesMember">
            <xs:selector xpath="oor:group|oor:set"/>
            <xs:field xpath="@oor:name"/>
          </xs:unique>
        </xs:element>
        <xs:element name="component">
          <xs:complexType>
            <xs:sequence>
              <xs:choice minOccurs="1" maxOccurs="unbounded">
                <xs:element name="prop" type="oor:prop"/>
                <xs:element name="node-ref" type="oor:node-ref"/>
                <xs:element name="group" type="oor:group">
                  <xs:unique name="groupMember1">
                    <xs:selector xpath="oor:group|oor:set|oor:node-ref|oor:prop"/>
                    <xs:field xpath="@oor:name"/>
                  </xs:unique>
                </xs:element>
                <xs:element name="set" type="oor:set"/>
              </xs:choice>
            </xs:sequence>
          </xs:complexType>
          <xs:unique name="schemaMember">
            <xs:selector xpath="oor:group|oor:set|oor:node-ref|oor:prop"/>
            <xs:field xpath="@oor:name"/>
          </xs:unique>
        </xs:element>
      </xs:sequence>
      <xs:attribute name="name" type="xs:NMTOKEN" use="required"/>
      <xs:attribute ref="oor:package"/>
      <xs:attribute name="version" type="xs:string" use="optional">
        <xs:annotation>
          <xs:documentation>identifies the version of the component. 
                    The version number should have the form major.minor.micro
          </xs:documentation>
        </xs:annotation>
      </xs:attribute>
      <xs:attribute ref="xml:lang" use="optional"/>
    </xs:complexType>
  </xs:element>
</xs:schema>



Appendix C - Registry Update Format (component-update.xsd)


<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://openoffice.org/2001/registry" 
    xmlns:oor="http://openoffice.org/2001/registry" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    elementFormDefault="unqualified" attributeFormDefault="qualified">
  <xs:annotation>
    <xs:documentation>defines the document format for configuration update documents.
         Updates are increments to default documents like a component schema and contain
         additional information for merging and access control.
    </xs:documentation>  
  </xs:annotation> 
  <xs:redefine schemaLocation="component-types.xsd">
    <xs:complexType name="value">
      <xs:annotation>
        <xs:documentation>adds the xml:lang attribute for localized information. 
                  Only the update format is allowed to contain localized data.
        </xs:documentation>
      </xs:annotation>
      <xs:simpleContent>
        <xs:extension base="oor:value">
          <xs:attribute ref="xml:lang"/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:redefine>
  <xs:complexType name="node">
    <xs:annotation>
      <xs:documentation>identifies a node in the schema 
          by it's name and position within the hierarchy. 
          Overrides or adds information from the base layer. 
          A node can be of type set or group.
      </xs:documentation>
    </xs:annotation>
    <xs:complexContent>
      <xs:extension base="oor:basic-node">
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element name="node" type="oor:node"/>
          <xs:element name="prop" type="oor:prop">
            <xs:unique name="uniqueLang">
              <xs:selector xpath="oor:value"/>
              <xs:field xpath="@xml:lang"/>
            </xs:unique>
          </xs:element>
        </xs:choice>
        <xs:attributeGroup ref="oor:update-info"/>
        <xs:attribute ref="oor:mandatory"/>
        <xs:attributeGroup ref="oor:node-type-info" use="optional"/>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:complexType name="prop">
    <xs:annotation>
      <xs:documentation>adds operational info to a property, 
          should only be applied for dynamic properties.
          Dynamic properties are not available in the component schema 
          and are added or removed during runtime.
      </xs:documentation>
    </xs:annotation>
    <xs:complexContent>
      <xs:extension base="oor:basic-prop">
        <xs:sequence minOccurs="0" maxOccurs="unbounded">
          <xs:element name="value" type="oor:value" nillable="true"/>
        </xs:sequence>
        <xs:attributeGroup ref="oor:update-info"/>
        <xs:attribute ref="oor:type" use="optional"/>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:attributeGroup name="update-info">
    <xs:attribute ref="oor:finalized"/>
    <xs:attribute ref="oor:readonly"/>
    <xs:attribute ref="oor:op"/>
  </xs:attributeGroup>
  <xs:attribute name="op" use="optional" default="modify">
    <xs:annotation>
      <xs:documentation>defines a list of possible operations, 
                which are applied during merging of node fragments.
      </xs:documentation>
    </xs:annotation>
    <xs:simpleType>
      <xs:restriction base="xs:string">
        <xs:enumeration value="modify"/>
        <xs:enumeration value="replace"/>
        <xs:enumeration value="fuse"/>
        <xs:enumeration value="remove"/>
        <xs:enumeration value="reset"/>
      </xs:restriction>
    </xs:simpleType>
  </xs:attribute>
  <xs:attribute name="finalized" type="xs:boolean" use="optional" default="false">
    <xs:annotation>
      <xs:documentation>indicates that the content of a node 
          and its descendant nodes are not allowed to be overwritten.
      </xs:documentation>
    </xs:annotation>
  </xs:attribute>
  <xs:attribute name="mandatory" type="xs:boolean" default="false">
    <xs:annotation>
      <xs:documentation>specifies that a node MUST be present 
          and can not be removed or replaced by a node during the merging process. 
      </xs:documentation>
    </xs:annotation>
  </xs:attribute>
  <xs:attribute name="readonly" type="xs:boolean" use="optional" default="false">
    <xs:annotation>
      <xs:documentation>determines, whether a node and its descendants are readonly or not. 
          This is a computed attribute and can not be set by an application.
      </xs:documentation>
    </xs:annotation>
  </xs:attribute>
  <xs:element name="component-data">
    <xs:annotation>
      <xs:documentation>root element of the update document.</xs:documentation>
    </xs:annotation>
    <xs:complexType>
      <xs:extension base="oor:basic-node">
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element name="node" type="oor:node"/>
          <xs:element name="prop" type="oor:prop">
            <xs:unique name="uniqueLang">
              <xs:selector xpath="oor:value"/>
              <xs:field xpath="@xml:lang"/>
            </xs:unique>
          </xs:element>
        </xs:choice>
        <xs:attributeGroup ref="oor:update-info"/>
        <xs:attribute ref="oor:package"/>
      </xs:extension>
    </xs:complexType>    
    <xs:unique name="member">
      <xs:selector xpath="oor:node|oor:prop"/>
      <xs:field xpath="@oor:name"/>
    </xs:unique>
  </xs:element>
</xs:schema>


Author: Dirk Grobler ($Date: 2006/04/05 16:20:15 $)
Copyright 2002-2004 Sun Microsystems, Inc. All Rights Reserved