# 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:

- Define an OCD.
- Associate an OCD with a PID (see Managed Services).

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.
    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.

    define('orion/plugin', function(PluginProvider) {
        var pluginProvider = new PluginProvider();
        pluginProvider.registerService('orion.cm.metatype',
            {},
            {  classes: [
                   {  id: 'example.customer',
                      properties: [
                          {  id: 'fullname',
                             name: 'Full Name',
                             type: 'string'
                          },
                          {  id: 'address',
                             name: 'Mailing Address',
                             type: 'string'
                          }
                      ]
                   }
               ]
            });
        provider.connect();
    });

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`.

    define('orion/plugin', function(PluginProvider) {
        var pluginProvider = new PluginProvider();
        pluginProvider.registerService('orion.cm.metatype',
            {},
            {  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',
            {},
            {  designates: [
                   {  pid: 'example.pid',
                      classId: 'example.customer'
                   }
               ]
            });
        provider.connect();
    });

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

    define('orion/plugin', function(PluginProvider) {
        var pluginProvider = new PluginProvider();
        pluginProvider.registerService('orion.cm.metatype',
            {},
            {  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();
    });