Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Orion/Documentation/Developer Guide/Configuration services"

(Fix incorrect param order in registerService() calls)
 
(65 intermediate revisions by 4 users not shown)
Line 1: Line 1:
= Overview =
+
= Overview of configuration services =
Orion provides a number of service APIs related to service configuration.  
+
Orion provides a number of service APIs related to service configuration. This page explains the service configuration APIs. For a basic overview of Orion's service architecture, see [[Orion/Documentation/Developer_Guide/Architecture#Services|Architecture]].
 
<!--  
 
<!--  
 
These APIs allow services to declare themselves as needing configuration data, and  
 
These APIs allow services to declare themselves as needing configuration data, and  
Line 8: Line 8:
  
 
== Managed Services ==
 
== Managed Services ==
A service may need configuration information before it can perform its intended functionality. Such services are called ''[[#orion.cm.managedservice|Managed Services]]''. A Managed Service implements a method, <code>updated()</code>, which is called by the Orion configuration framework to provide configuration data to the service. (As with all service methods, updated() is called asynchronously.) Configuration data takes the form of a dictionary of key-value pairs, called properties. If no configuration data exists for the Managed Service, <code>null</code> is passed.
+
A service may need configuration information before it can perform its intended functionality. Such services are called ''[[#orion.cm.managedservice|Managed Services]]''. A Managed Service implements a method, <code>updated()</code>, which is called by the Orion configuration framework to provide configuration data to the service. As with all service methods, <code>updated()</code> is called asynchronously. The configuration data takes the form of a dictionary of key-value pairs, called ''properties''. If no configuration data exists for the Managed Service, <code>null</code> properties are passed.
  
A Managed Service needs to receive its configuration information before the service is invoked to perform other work. For example, a configurable validation service would want to receive the values of any custom validation options (or <code>null</code, if no custom values were configured) before actually performing any validation. For this reason, the framework guarantees that a Managed Service's updated() method will be called prior to any other service methods the service may implement.
+
A Managed Service needs to receive its configuration information before the service is invoked to perform other work. For example, a configurable [[Orion/Documentation/Developer_Guide/Plugging_into_the_editor#orion.edit.validator|validation service]] would want to receive any custom validation options (or <code>null</code>, if no custom options were configured) before actually performing any validation. For this reason, the framework guarantees that a Managed Service's <code>updated()</code> method will be called prior to any other service methods the service may implement.
  
Managed Services are registered with a ''PID'' (persistent identifier) which uniquely identifies the configuration information for the service.
+
To contribute a Managed Service, we register a service having the name [[#orion.cm.managedservice|orion.cm.managedservice]]. Every Managed Service must provide a service property named <code>"pid"</code> which gives a ''PID'' (persistent identifier). The PID serves as primary key, uniquely identifying the configuration information of a Managed Service.
  
 
The Orion concept of a Managed Service is analogous to the OSGi [http://www.osgi.org/javadoc/r4v42/org/osgi/service/cm/ManagedService.html Managed Service].
 
The Orion concept of a Managed Service is analogous to the OSGi [http://www.osgi.org/javadoc/r4v42/org/osgi/service/cm/ManagedService.html Managed Service].
  
 
== Meta Typing ==
 
== Meta Typing ==
A ''metatype'' describes the shape of configuration data. In other words, it specifies what property names can appear in the properties dictionary, and what data types (string, boolean, number, etc) their values may have. Metatype information is defined in terms of "object classes", which can be reused. Metatype information is keyed by a configuration's PID. Metatype information is optional, so not every Managed Service need have metatype information associated with it.  
+
A ''Metatype'' describes the shape of configuration data*. In other words, it specifies what property names can appear in the properties dictionary, and what data types their values may have (string, boolean, number, etc). Metatype information is defined in terms of ''Object Class Definitions'' (OCDs), which can be reused. Metatype information is associated with a Managed Service's PID. Metatype information is optional, so not every Managed Service need have Metatype information associated with it.
  
Metatype information is contributed by services with the [[#orion.cm.metatype|orion.cm.metatype]] service name.
+
Metatype information can be contributed by registering a service with the [[#orion.cm.metatype|orion.cm.metatype]] service name.
  
 
The Orion concept of a Metatype is analogous to the OSGi Metatype.
 
The Orion concept of a Metatype is analogous to the OSGi Metatype.
 +
 +
:<nowiki>*</nowiki> In this page we discuss Metatype information solely in the context of configuration management. Strictly speaking, Metatypes are generic, and can be used for other purposes.
  
 
== Configuration management ==
 
== Configuration management ==
 
Configuration data is managed by a ''ConfigurationAdmin'' service, which maintains a database of Configuration objects. The ConfigurationAdmin monitors the service registry and provides configuration data to Managed Services that are registered. Orion's implementation of ConfigurationAdmin persists configuration data to a [[Orion/Documentation/Developer_Guide/Core_client_services#orion.core.preference|Preferences Service]].
 
Configuration data is managed by a ''ConfigurationAdmin'' service, which maintains a database of Configuration objects. The ConfigurationAdmin monitors the service registry and provides configuration data to Managed Services that are registered. Orion's implementation of ConfigurationAdmin persists configuration data to a [[Orion/Documentation/Developer_Guide/Core_client_services#orion.core.preference|Preferences Service]].
  
In JavaScript code, configuration information is represented as <code>Configuration</code> objects (refer to "orion.cm.Configuration" in the client API reference for details), which are returned by the ConfigurationAdmin's service methods. Because the ConfigurationAdmin service is currently only accessible to page code, Configuration objects can only be managed from page code. Managed Services currently cannot interact with Configurations directly, and can only receive configuration information via their <code>updated()</code> method.
+
In JavaScript code, configuration information is represented as <code>Configuration</code> objects, which are returned by the ConfigurationAdmin's service methods. (Refer to "orion.cm.Configuration" in the client API reference for JSDoc.) Because the ConfigurationAdmin service is currently only accessible to code running in the same window as the service registry, Configuration objects cannot be directly interacted with by external services. Therefore a plugin's Managed Services can only receive configuration information via their <code>updated()</code> method.  
  
 
The Orion ConfigurationAdmin service is analogous to the OSGi [http://www.osgi.org/javadoc/r4v42/org/osgi/service/cm/ConfigurationAdmin.html ConfigurationAdmin].
 
The Orion ConfigurationAdmin service is analogous to the OSGi [http://www.osgi.org/javadoc/r4v42/org/osgi/service/cm/ConfigurationAdmin.html ConfigurationAdmin].
  
 
== Settings ==
 
== Settings ==
On top of the basic configuration and metatype APIs, Orion also provides a higher-level Settings API.
+
On top of the basic configuration and metatype APIs, Orion also provides a higher-level Settings API. See [[Orion/Documentation/Developer Guide/Plugging into the settings page|Plugging into the settings page]] for details.
  
 
= orion.cm.configadmin =
 
= orion.cm.configadmin =
The <code>orion.cm.configadmin</code> service, also called ''ConfigurationAdmin'', provides management of configuration data. Internally, the ConfigurationAdmin service is used by the [[Orion/Documentation/Developer Guide/Plugging into the settings page|Plugin Settings]] page to manage the values of [[Orion/Documentation/Developer guide/Plugging into the settings page#orion.core.setting|settings]].
+
The <code>orion.cm.configadmin</code> service, also called ''ConfigurationAdmin'', provides management of configuration information. Internally, the ConfigurationAdmin service is used by the [[Orion/Documentation/Developer Guide/Plugging into the settings page|Settings page]] to manage the values of [[Orion/Documentation/Developer Guide/Plugging into the settings page#orion.core.setting|plugin Settings]].
  
 
The service methods are:
 
The service methods are:
  
 
; getConfiguration(pid)
 
; getConfiguration(pid)
: Returns a Configuration with the given PID, creating a new Configuration if one does not already exist.
+
: Returns the Configuration with the given PID from the database. If no such Configuration exists, a new one is created and then returned.
 
; listConfigurations()
 
; listConfigurations()
: Returns an array of all current Configuration objects.
+
: Returns an array of all current Configuration objects from the database.
  
 
Refer to <code>orion.cm.ConfigurationAdmin</code> in the client API reference for a full description of this service's API methods.
 
Refer to <code>orion.cm.ConfigurationAdmin</code> in the client API reference for a full description of this service's API methods.
  
 
Here is an example of how to use the ConfigurationAdmin service to print out all existing configurations and their property values:
 
Here is an example of how to use the ConfigurationAdmin service to print out all existing configurations and their property values:
 +
<source lang="javascript" enclose="div" line="GESHI_FANCY_LINE_NUMBERS">
 
  var configurations = serviceRegistry.getService("orion.cm.configadmin").listConfigurations().then(function(configurations) {
 
  var configurations = serviceRegistry.getService("orion.cm.configadmin").listConfigurations().then(function(configurations) {
 
         configurations.forEach(function(configuration) {
 
         configurations.forEach(function(configuration) {
Line 59: Line 62:
 
         });
 
         });
 
  });
 
  });
 +
</source>
 
The result might look something like this:
 
The result might look something like this:
 
  Configuration pid: nonnls.config
 
  Configuration pid: nonnls.config
Line 72: Line 76:
 
Contributes a ''Managed Service''. A Managed Service is a service that can receive configuration data.
 
Contributes a ''Managed Service''. A Managed Service is a service that can receive configuration data.
  
 +
== Service properties ==
 +
A Managed Service must define the following property:
 +
; pid
 +
: <code>String</code> Gives the PID for this Managed Service.
 +
 +
== Service methods ==
 
A Managed Service must implement the following method:
 
A Managed Service must implement the following method:
: updated(properties)
+
; updated(properties)
; The ConfigurationAdmin invokes this method to provide configuration to this Managed Service. If no configuration exists for this Managed Service's PID, <code>properties</code> will be <code>null</code>. Otherwise, <code>properties</code> is an object containing the service's configuration data.
+
: The ConfigurationAdmin invokes this method to provide configuration to this Managed Service. If no configuration exists for this Managed Service's PID, <code>properties</code> is <code>null</code>. Otherwise, <code>properties</code> is a dictionary containing the service's configuration data.
 +
 
 +
== Example 1: minimal ==
 +
This minimal example shows the implementation of a plugin which registers a Managed Service under the PID "example.pid". When its updated() method is called, it simply prints out what it received:
 +
<source lang="javascript" enclose="div" line="GESHI_FANCY_LINE_NUMBERS">
 +
define(["orion/plugin"], function(PluginProvider) {
 +
    var provider = new PluginProvider();
 +
    provider.registerService(["orion.cm.managedservice"],
 +
        {  updated: function(properties) {
 +
                if (properties === null) {
 +
                  console.log("We have no properties :(");
 +
                } else {
 +
                  console.log("We got properties!");
 +
                  console.dir(properties);
 +
                }
 +
            }
 +
        },
 +
        {  pid: "example.pid"
 +
        });
 +
    provider.connect();
 +
});
 +
</source>
 +
 
 +
== Example 2: validator ==
 +
Here is a larger example, showing how a validation service can accept options through its configuration properties. This validation service provides a spellchecker, which checks for any occurrences of the misspelling "definately". In this example, the service is both a validator and a Managed Service: note how its properties and methods fulfill the contract of both [[Orion/Documentation/Developer_Guide/Plugging_into_the_editor#orion.edit.validator|orion.edit.validator]] and [[Orion/Documentation/Developer_Guide/Configuration_services#orion.cm.managedservice|orion.cm.managedservice]].
 +
 
 +
<source lang="javascript" enclose="div" line="GESHI_FANCY_LINE_NUMBERS">
 +
define(["orion/plugin"], function(PluginProvider) {
 +
    var provider = new PluginProvider();
 +
    var options;
 +
    provider.registerService(["orion.cm.managedservice", "orion.edit.validator"],
 +
        // Service methods
 +
        {
 +
            // Method of orion.cm.managedservice
 +
            updated: function(properties) {
 +
                if (properties === null) {
 +
                    // No configuration, use default
 +
                    options = { enabled: true };
 +
                } else {
 +
                    options = { enabled: !!properties.enabled };
 +
                }
 +
            },
 +
            // Method of orion.edit.validator
 +
            checkSyntax: function(title, contents) {
 +
                if (!options.enabled) {
 +
                    return { problems: [] };
 +
                }
 +
                var problems = [];
 +
                contents.split(/\r?\n/).forEach(function(line, i) {
 +
                    var index;
 +
                    if ((index = line.indexOf("definately") !== -1) {
 +
                        problems.push({
 +
                            description: "Misspelled word",
 +
                            line: i+1,
 +
                            start: index,
 +
                            end: index+10,
 +
                            severity: "warning"
 +
                        });
 +
                    }
 +
                });
 +
                return { problems: problems };
 +
            }
 +
        },
 +
        // Service properties
 +
        {  pid: "example.validator",    // property of orion.cm.managedservice
 +
            contentType: ["text/plain"]  // property of orion.edit.validator
 +
        });
 +
    provider.connect();
 +
});
 +
</source>
 +
The <code>updated()</code> method here checks its configuration dictionary for a boolean <code>enabled</code> property that determines whether the validator is active. In the case of <code>null</code> properties, the service uses a reasonable default. (It's a best practice for configurable services to behave sanely when no configuration has been defined for them.)
 +
 
 +
Note that, by virtue of the configuration framework's guarantee that <code>updated()</code> is called before all other service methods, our <code>checkSyntax()</code> method can safely assume that the <code>options</code> variable has been set.
  
 
= orion.cm.metatype =
 
= orion.cm.metatype =
Contributes type definitions, which may be associated with a service's configuration.
+
The <code>orion.cm.metatype</code> service contributes Metatype information. Metatype information is based around ''Object Class Definitions'' (OCDs), which are first-class reusable elements. An OCD contains one or more ''Attribute Definitions''. An Attribute Definition defines an individual property that can appear within a particular instance of the containing OCD.
  
 +
The <code>orion.cm.metatype</code> service serves two purposes:
 +
* Define an OCD.
 +
* Associate an OCD with a PID (see [[#Managed_Services|Managed Services]]).
 +
 +
Object Classes are analogous to OSGi [http://www.osgi.org/javadoc/r4v42/org/osgi/service/metatype/ObjectClassDefinition.html Object Class Definitions], and Attribute Definitions to OSGi [http://www.osgi.org/javadoc/r4v42/org/osgi/service/metatype/AttributeDefinition.html Attribute Definitions]. In OO terms, Object Classes are similar to classes, and Attribute Definitions are similar to fields or instance variables.
 +
 +
== Service properties ==
 +
There are two top-level properties: '''classes''' (defines an OCD), and '''designates''' (associates an OCD with a PID). Either of these properties, or both of them, may be specified.
 +
 +
=== Define an OCD ===
 +
To define one or more Object Class Definitions, the '''classes''' service property is used:
 +
; classes
 +
: <code>ObjectClass[]</code>.  Defines Object Classes. Object Classes defined here can be referenced elsewhere by their ID. Each <code>ObjectClass</code> element has the following shape:
 +
:; id
 +
:: <code>String</code>. Uniquely identifies this OCD.
 +
:; name
 +
:: <code>String</code>. ''Optional.'' The name of this OCD.
 +
:; properties
 +
:: <code>AttributeDefinition[]</code>. Defines the Attribute Definitions that can appear in instances of this OCD. Each <code>AttributeDefinition</code> element has the following shape:
 +
::; id
 +
::: <code>String</code>. The property id. This is unique within the containing OCD.
 +
::; name
 +
::: <code>String</code>. ''Optional''. The name of this property.
 +
::; nameKey
 +
:: <code>String</code>. ''Optional.'' The key used to look up the translated, human readable name of this property within a message bundle. Because OCDs and AttributeDefinitions do not specify a message bundle, the <code>nameKey</code> property is used only when an AttributeDefinition appears within an [[Orion/Documentation/Developer Guide/Core client services#orion.core.setting|<code>orion.core.setting</code>]], which specifies the message bundle to be used.
 +
::; type
 +
::: <code>'string' | 'number' | 'boolean'</code>. ''Optional, defaults to 'string'''. The data type.
 +
::; defaultValue
 +
::: <code>Object</code>. ''Optional, defaults to <code>null</code>''. The default value of this property. This is a literal whose type matches the property's '''type'''.
 +
::; options
 +
::: <code>PropertyOption[].</code> ''Optional, defaults to <code>null</code>''. If nonnull, gives an enumeration of allowed values that this property can take. Each <code>PropertyOption</code> element has the following shape:
 +
:::; value
 +
:::: <code>Object</code>. The value of this option. This is a literal value whose type matches the property's '''type'''.
 +
:::; label
 +
:::: <code>String</code>. The label for this option.
 +
 +
 +
=== Associate an OCD with a PID ===
 +
To create PID-to-Object-Class associations, the '''designates''' service property is used:
 +
; designates
 +
: <code>Designate[]</code>. Each <code>Designate</code> element has the following shape:
 +
:; pid
 +
:: <code>String</code>. The PID for which OCD information will be associated.
 +
:; classId
 +
:: <code>String</code>. References an OCD by ID. The referenced OCD will be associated with the PID.
 +
 +
Object Classes are publicly visible, so the OCD referenced by a Designate element may be defined by a different Metatype service. The order in which Metatype services are registered does not matter.
 +
 +
== Service methods ==
 +
None. This service is purely declarative.
 +
 +
== Examples ==
 +
This example shows how to define an OCD with ID <code>example.customer</code>. The OCD has two AttributeDefinitions.
 +
<source lang="javascript" enclose="div" line="GESHI_FANCY_LINE_NUMBERS">
 +
define(['orion/plugin'], function(PluginProvider) {
 +
    var pluginProvider = new PluginProvider();
 +
    pluginProvider.registerService('orion.cm.metatype',
 +
        {}, // no methods
 +
        {  classes: [
 +
                {  id: 'example.customer',
 +
                  properties: [
 +
                      {  id: 'fullname',
 +
                          name: 'Full Name',
 +
                          type: 'string'
 +
                      },
 +
                      {  id: 'address',
 +
                          name: 'Mailing Address',
 +
                          type: 'string'
 +
                      }
 +
                  ]
 +
                }
 +
            ]
 +
        });
 +
    provider.connect();
 +
});
 +
</source>
 +
Building on the previous example, here's how we would use a '''designates''' to associate the <code>example.customer</code> OCD with a PID named <code>example.pid</code>.
 +
<!-- line highlight="20-28" -->
 +
<source lang="javascript" enclose="div" line="GESHI_FANCY_LINE_NUMBERS">
 +
define(['orion/plugin'], function(PluginProvider) {
 +
    var pluginProvider = new PluginProvider();
 +
    pluginProvider.registerService('orion.cm.metatype',
 +
        {}, // no methods
 +
        {  classes: [
 +
                {  id: 'example.customer',
 +
                  properties: [
 +
                      {  id: 'fullname',
 +
                          name: 'Full Name',
 +
                          type: 'string'
 +
                      },
 +
                      {  id: 'address',
 +
                          name: 'Mailing Address',
 +
                          type: 'string'
 +
                      }
 +
                  ]
 +
                }
 +
            ]
 +
        });
 +
    // New code starts here
 +
    pluginProvider.registerService('orion.cm.metatype',
 +
        {}, // no methods
 +
        {  designates: [
 +
                {  pid: 'example.pid',
 +
                  classId: 'example.customer'
 +
                }
 +
            ]
 +
        });
 +
    provider.connect();
 +
});
 +
</source>
 +
Alternatively, we can use a single service registration, with both '''classes''' and '''designates''', to achieve the same effect:
 +
<!-- highlight="5-24" -->
 +
<source lang="javascript" enclose="div" line="GESHI_FANCY_LINE_NUMBERS">
 +
define(['orion/plugin'], function(PluginProvider) {
 +
    var pluginProvider = new PluginProvider();
 +
    pluginProvider.registerService('orion.cm.metatype',
 +
        {}, // no methods
 +
        {  classes: [
 +
                {  id: 'example.customer',
 +
                  properties: [
 +
                      {  id: 'fullname',
 +
                          name: 'Full Name',
 +
                          type: 'string'
 +
                      },
 +
                      {  id: 'address',
 +
                          name: 'Mailing Address',
 +
                          type: 'string'
 +
                      }
 +
                  ]
 +
                }
 +
            ],
 +
            designates: [
 +
                {  pid: 'example.pid',
 +
                  classId: 'example.customer'
 +
                }
 +
            ]
 +
        });
 +
    provider.connect();
 +
});
 +
</source>
 
= See also =
 
= See also =
[[Orion/Documentation/Developer Guide/Plugging into the settings page|Plugging into the settings page]]
+
[[Orion/Documentation/Developer_Guide/Core_client_services#orion.core.setting|orion.core.setting]]

Latest revision as of 16:44, 9 September 2014

Overview of configuration services

Orion provides a number of service APIs related to service configuration. This page explains the service configuration APIs. For a basic overview of Orion's service architecture, see Architecture.

Managed Services

A service may need configuration information before it can perform its intended functionality. Such services are called Managed Services. A Managed Service implements a method, updated(), which is called by the Orion configuration framework to provide configuration data to the service. As with all service methods, updated() is called asynchronously. The configuration data takes the form of a dictionary of key-value pairs, called properties. If no configuration data exists for the Managed Service, null properties are passed.

A Managed Service needs to receive its configuration information before the service is invoked to perform other work. For example, a configurable validation service would want to receive any custom validation options (or null, if no custom options were configured) before actually performing any validation. For this reason, the framework guarantees that a Managed Service's updated() method will be called prior to any other service methods the service may implement.

To contribute a Managed Service, we register a service having the name orion.cm.managedservice. Every Managed Service must provide a service property named "pid" which gives a PID (persistent identifier). The PID serves as primary key, uniquely identifying the configuration information of a Managed Service.

The Orion concept of a Managed Service is analogous to the OSGi Managed Service.

Meta Typing

A Metatype describes the shape of configuration data*. In other words, it specifies what property names can appear in the properties dictionary, and what data types their values may have (string, boolean, number, etc). Metatype information is defined in terms of Object Class Definitions (OCDs), which can be reused. Metatype information is associated with a Managed Service's PID. Metatype information is optional, so not every Managed Service need have Metatype information associated with it.

Metatype information can be contributed by registering a service with the orion.cm.metatype service name.

The Orion concept of a Metatype is analogous to the OSGi Metatype.

* In this page we discuss Metatype information solely in the context of configuration management. Strictly speaking, Metatypes are generic, and can be used for other purposes.

Configuration management

Configuration data is managed by a ConfigurationAdmin service, which maintains a database of Configuration objects. The ConfigurationAdmin monitors the service registry and provides configuration data to Managed Services that are registered. Orion's implementation of ConfigurationAdmin persists configuration data to a Preferences Service.

In JavaScript code, configuration information is represented as Configuration objects, which are returned by the ConfigurationAdmin's service methods. (Refer to "orion.cm.Configuration" in the client API reference for JSDoc.) Because the ConfigurationAdmin service is currently only accessible to code running in the same window as the service registry, Configuration objects cannot be directly interacted with by external services. Therefore a plugin's Managed Services can only receive configuration information via their updated() method.

The Orion ConfigurationAdmin service is analogous to the OSGi ConfigurationAdmin.

Settings

On top of the basic configuration and metatype APIs, Orion also provides a higher-level Settings API. See Plugging into the settings page for details.

orion.cm.configadmin

The orion.cm.configadmin service, also called ConfigurationAdmin, provides management of configuration information. Internally, the ConfigurationAdmin service is used by the Settings page to manage the values of plugin Settings.

The service methods are:

getConfiguration(pid)
Returns the Configuration with the given PID from the database. If no such Configuration exists, a new one is created and then returned.
listConfigurations()
Returns an array of all current Configuration objects from the database.

Refer to orion.cm.ConfigurationAdmin in the client API reference for a full description of this service's API methods.

Here is an example of how to use the ConfigurationAdmin service to print out all existing configurations and their property values:

  1.  var configurations = serviceRegistry.getService("orion.cm.configadmin").listConfigurations().then(function(configurations) {
  2.          configurations.forEach(function(configuration) {
  3.              var properties = configuration.getProperties();
  4.              var propertyInfo = Object.keys(properties).map(function(propertyName) {
  5.                  if (propertyName !== "pid") {
  6.                      return "\n        " + propertyName + ": " + JSON.stringify(properties[propertyName]) + "\n";
  7.                  }
  8.              }).join("");
  9.              console.log("Configuration pid: " + configuration.getPid() + "\n"
  10.                        + "  properties: {" + propertyInfo + "\n"
  11.                        + "  }");
  12.          });
  13.  });

The result might look something like this:

Configuration pid: nonnls.config
  properties: {
        enabled: false
  }
Configuration pid: jslint.config
  properties: {
        options: "laxbreak:true, maxerr:50"
  }

orion.cm.managedservice

Contributes a Managed Service. A Managed Service is a service that can receive configuration data.

Service properties

A Managed Service must define the following property:

pid
String Gives the PID for this Managed Service.

Service methods

A Managed Service must implement the following method:

updated(properties)
The ConfigurationAdmin invokes this method to provide configuration to this Managed Service. If no configuration exists for this Managed Service's PID, properties is null. Otherwise, properties is a dictionary containing the service's configuration data.

Example 1: minimal

This minimal example shows the implementation of a plugin which registers a Managed Service under the PID "example.pid". When its updated() method is called, it simply prints out what it received:

  1.  define(["orion/plugin"], function(PluginProvider) {
  2.      var provider = new PluginProvider();
  3.      provider.registerService(["orion.cm.managedservice"],
  4.          {  updated: function(properties) {
  5.                 if (properties === null) {
  6.                   console.log("We have no properties :(");
  7.                 } else {
  8.                   console.log("We got properties!");
  9.                   console.dir(properties);
  10.                 }
  11.             }
  12.          },
  13.          {  pid: "example.pid"
  14.          });
  15.      provider.connect();
  16.  });

Example 2: validator

Here is a larger example, showing how a validation service can accept options through its configuration properties. This validation service provides a spellchecker, which checks for any occurrences of the misspelling "definately". In this example, the service is both a validator and a Managed Service: note how its properties and methods fulfill the contract of both orion.edit.validator and orion.cm.managedservice.

  1.  define(["orion/plugin"], function(PluginProvider) {
  2.      var provider = new PluginProvider();
  3.      var options;
  4.      provider.registerService(["orion.cm.managedservice", "orion.edit.validator"],
  5.          // Service methods
  6.          {
  7.             // Method of orion.cm.managedservice
  8.             updated: function(properties) {
  9.                 if (properties === null) {
  10.                     // No configuration, use default
  11.                     options = { enabled: true };
  12.                 } else {
  13.                     options = { enabled: !!properties.enabled };
  14.                 }
  15.             },
  16.             // Method of orion.edit.validator
  17.             checkSyntax: function(title, contents) {
  18.                 if (!options.enabled) {
  19.                     return { problems: [] };
  20.                 }
  21.                 var problems = [];
  22.                 contents.split(/\r?\n/).forEach(function(line, i) {
  23.                     var index;
  24.                     if ((index = line.indexOf("definately") !== -1) {
  25.                         problems.push({
  26.                             description: "Misspelled word",
  27.                             line: i+1,
  28.                             start: index,
  29.                             end: index+10,
  30.                             severity: "warning"
  31.                         });
  32.                     }
  33.                 });
  34.                 return { problems: problems };
  35.             }
  36.          },
  37.          // Service properties
  38.          {  pid: "example.validator",    // property of orion.cm.managedservice
  39.             contentType: ["text/plain"]  // property of orion.edit.validator
  40.          });
  41.      provider.connect();
  42.  });

The updated() method here checks its configuration dictionary for a boolean enabled property that determines whether the validator is active. In the case of null properties, the service uses a reasonable default. (It's a best practice for configurable services to behave sanely when no configuration has been defined for them.)

Note that, by virtue of the configuration framework's guarantee that updated() is called before all other service methods, our checkSyntax() method can safely assume that the options variable has been set.

orion.cm.metatype

The orion.cm.metatype service contributes Metatype information. Metatype information is based around Object Class Definitions (OCDs), which are first-class reusable elements. An OCD contains one or more Attribute Definitions. An Attribute Definition defines an individual property that can appear within a particular instance of the containing OCD.

The orion.cm.metatype service serves two purposes:

Object Classes are analogous to OSGi Object Class Definitions, and Attribute Definitions to OSGi Attribute Definitions. In OO terms, Object Classes are similar to classes, and Attribute Definitions are similar to fields or instance variables.

Service properties

There are two top-level properties: classes (defines an OCD), and designates (associates an OCD with a PID). Either of these properties, or both of them, may be specified.

Define an OCD

To define one or more Object Class Definitions, the classes service property is used:

classes
ObjectClass[]. Defines Object Classes. Object Classes defined here can be referenced elsewhere by their ID. Each ObjectClass element has the following shape:
id
String. Uniquely identifies this OCD.
name
String. Optional. The name of this OCD.
properties
AttributeDefinition[]. Defines the Attribute Definitions that can appear in instances of this OCD. Each AttributeDefinition element has the following shape:
id
String. The property id. This is unique within the containing OCD.
name
String. Optional. The name of this property.
nameKey
String. Optional. The key used to look up the translated, human readable name of this property within a message bundle. Because OCDs and AttributeDefinitions do not specify a message bundle, the nameKey property is used only when an AttributeDefinition appears within an orion.core.setting, which specifies the message bundle to be used.
type
'string' | 'number' | 'boolean'. Optional, defaults to 'string'. The data type.
defaultValue
Object. Optional, defaults to null. The default value of this property. This is a literal whose type matches the property's type.
options
PropertyOption[]. Optional, defaults to null. If nonnull, gives an enumeration of allowed values that this property can take. Each PropertyOption element has the following shape:
value
Object. The value of this option. This is a literal value whose type matches the property's type.
label
String. The label for this option.


Associate an OCD with a PID

To create PID-to-Object-Class associations, the designates service property is used:

designates
Designate[]. Each Designate element has the following shape:
pid
String. The PID for which OCD information will be associated.
classId
String. References an OCD by ID. The referenced OCD will be associated with the PID.

Object Classes are publicly visible, so the OCD referenced by a Designate element may be defined by a different Metatype service. The order in which Metatype services are registered does not matter.

Service methods

None. This service is purely declarative.

Examples

This example shows how to define an OCD with ID example.customer. The OCD has two AttributeDefinitions.

  1.  define(['orion/plugin'], function(PluginProvider) {
  2.      var pluginProvider = new PluginProvider();
  3.      pluginProvider.registerService('orion.cm.metatype',
  4.          {}, // no methods
  5.          {  classes: [
  6.                 {  id: 'example.customer',
  7.                    properties: [
  8.                        {  id: 'fullname',
  9.                           name: 'Full Name',
  10.                           type: 'string'
  11.                        },
  12.                        {  id: 'address',
  13.                           name: 'Mailing Address',
  14.                           type: 'string'
  15.                        }
  16.                    ]
  17.                 }
  18.             ]
  19.          });
  20.      provider.connect();
  21.  });

Building on the previous example, here's how we would use a designates to associate the example.customer OCD with a PID named example.pid.

  1.  define(['orion/plugin'], function(PluginProvider) {
  2.      var pluginProvider = new PluginProvider();
  3.      pluginProvider.registerService('orion.cm.metatype',
  4.          {}, // no methods
  5.          {  classes: [
  6.                 {  id: 'example.customer',
  7.                    properties: [
  8.                        {  id: 'fullname',
  9.                           name: 'Full Name',
  10.                           type: 'string'
  11.                        },
  12.                        {  id: 'address',
  13.                           name: 'Mailing Address',
  14.                           type: 'string'
  15.                        }
  16.                    ]
  17.                 }
  18.             ]
  19.          });
  20.      // New code starts here
  21.      pluginProvider.registerService('orion.cm.metatype',
  22.          {}, // no methods
  23.          {  designates: [
  24.                 {  pid: 'example.pid',
  25.                    classId: 'example.customer'
  26.                 }
  27.             ]
  28.          });
  29.      provider.connect();
  30.  });

Alternatively, we can use a single service registration, with both classes and designates, to achieve the same effect:

  1.  define(['orion/plugin'], function(PluginProvider) {
  2.      var pluginProvider = new PluginProvider();
  3.      pluginProvider.registerService('orion.cm.metatype',
  4.          {}, // no methods
  5.          {  classes: [
  6.                 {  id: 'example.customer',
  7.                    properties: [
  8.                        {  id: 'fullname',
  9.                           name: 'Full Name',
  10.                           type: 'string'
  11.                        },
  12.                        {  id: 'address',
  13.                           name: 'Mailing Address',
  14.                           type: 'string'
  15.                        }
  16.                    ]
  17.                 }
  18.             ],
  19.             designates: [
  20.                 {  pid: 'example.pid',
  21.                    classId: 'example.customer'
  22.                 }
  23.             ]
  24.          });
  25.      provider.connect();
  26.  });

See also

orion.core.setting

Back to the top