Previous Topic

Next Topic

Book Contents

Book Index

Metatype Service

Provides information about using the OSGi Metatype Service to manage metatype information for a bundle containing metatype resources or MetaTypeProvider objects.

Overview

The OSGi Metatype Service of the Metatype Bundle delivers metatype information for a bundle. It implements the OSGi Metatype Service from the OSGi Service Platform Service Compendium, Release 6.

Registering Bundle

The service is registered by OSGi Metatype Bundle.

Metadata Model

The metadata management model of the OSGi Metatype Service Specification is based on definitions of object classes and of their attributes. A collection of object classes and attributes associated with a common entity define a metatype for that entity. The structure of an object class is described in its ObjectClassDefinition, which consists of zero or more AttributeDefinitions for required and/or optional attributes. Metadata within a metatype is delivered by a Metatype Provider, which holds ObjectClassDefinitions, each identified by its Persistent IDentity (PID).

In addition, the implementation of the Metatype Specification (from the OSGi Service Platform Specification, Release 3) associates each Metatype Provider with ID and version.

Provide a Metatype

Object classes and their attributes can be described :

Metatype XML Resource

A metatype resource contains a XML definition of metatypes and must be placed in the bundle JAR file. It should reside in the OSGi-INF/metatype directory of the bundle. The metatype resource should follow the XML schema defined in the OSGi Metatype Service from the OSGi Service Platform Service Compendium. For optimization the information provided within a XML metatype resource is persistently stored in the DB Bundle in the custom DB with METATYPE storage directory name.

Following is an example XML metatype resource:

Listing 1. An example XML metatype resource.

    
<?xml version="1.0" encoding="UTF-8"?>
<metatype:MetaData xmlns:metainfo="http://www.osgi.org/xmlns/metatype/v1.0.0">
  <OCD description="Object Class Definition Description"
       name="Object Class Definition Name"
       id="com.example.mybundle.pid">
    <AD name="Attribute Definition Name"
        id="attribute"
        required="true"
        type="String"
        default="Attribute Definition Default Value">
         <Option label="Label 1"
                 value="Value 1"/>
         <Option label="Label 2"
                 value="Value 2"/>
    </AD>
  </OCD>
</metatype:MetaData>

For another example of a metatype resource, refer to the Config Bundle documentation.

The SDK implementation of the schema for metatype XML resources slightly deviates from the one defined in the OSGi Metatype Service Specification. If you want to create configuration Object Class Definition, use the <Designate> element with attributes "pid", set to the configuration PID, and "factory" set to false. In case of a configuration factory, set the "factoryPid" attribute to the PID of the configuration Object Class Definition, the value of the "factory" element is not taken into consideration.

MetaTypeProvider Implementation

You can define metadata through MetaTypeProvider objects. The following example uses the Managed Service (org.osgi.service.cm.ManagedService) and implements the MetaTypeProvider interface to provide configuration metadata. It uses the ObjectClassDefinition and AttributeDefinition shown in Listings 3.2 and 3.3 in the "MetaTypeProvider Implementation" section of the "Metatype Extension" document.

Listing 2. An example Metatype Provider.

import java.util.Dictionary;
import java.util.Hashtable;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedService;
import org.osgi.service.metatype.AttributeDefinition;
import org.osgi.service.metatype.MetaTypeProvider;
import org.osgi.service.metatype.ObjectClassDefinition;


public class MyMetaTypeProvider implements BundleActivator, MetaTypeProvider,
         ManagedService{

  private OCD ocd = null;
  AD [] attrDefinitions = new AD[2];
  protected static String PID = "mypid.pid";
  ServiceRegistration sReg = null;
  ServiceRegistration configReg = null;

  // Method inherited from BundleActivator
  public void start(BundleContext bc) throws Exception {

  // Creating an ObjectClassDefinition
  attrDefinitions[0] = new AD("My Attribute Definition", AttributeDefinition.BOOLEAN, 0);
  attrDefinitions[0].setDefaultValue(new String[] { "false" });
  attrDefinitions[1] = new AD("port", AttributeDefinition.INTEGER, 0);
  attrDefinitions[1].setDefaultValue(new String[] { "5983" });
  ocd = new OCD(PID, attrDefinitions);
  ocd.setName("My Example Metatype");

  // Registering the Metatype Provider
  Hashtable regProps = new Hashtable();
  regProps.put(Constants.SERVICE_PID, PID);
  regProps.put("metadata.type", "Config");
  sReg = bc.registerService(MetaTypeProvider.class.getName(), this, regProps);

  // Registering the Managed Service
  Hashtable configProps = new Hashtable();
  configProps.put(Constants.SERVICE_PID, PID);
  configReg = bc.registerService(ManagedService.class.getName(), this, configProps);
  }

  // Method inherited from BundleActivator
  public void stop(BundleContext bc) throws Exception {
    if (sReg != null) {
    sReg.unregister();
    }
    if (configReg != null) {
    configReg.unregister();
    }
    ocd = null;
  }
  // Methods inherited from MetaTypeProvider
  public String[] getLocales() {
  return null;
  }

  public ObjectClassDefinition getObjectClassDefinition(String pid,
    String locale) {
    return ocd;
  }

  // Method inherited from ManagedService
  public void updated(Dictionary props) throws ConfigurationException {
            
                    ...  
  }
}

The SDK implementation of the OSGi Metatype Service Specification gives you the opportunity to provide as separate services (in the same bundle or in separate bundles) an org.osgi.service.metatype.MetaTypeProvider and the corresponding org.osgi.service.cm.ManagedService or org.osgi.service.cm.ManagedServiceFactory. In this case, define a MetaTypeProvider service property "metadata.type" equal to "Config" in the case of a ManagedService or "FactoryConfig" in the case of a ManagedServiceFactory.

Using the OSGi Metatype Service

The OSGi Metatype Service interface is org.osgi.service.metatype.MetaTypeService. It provides a unified way for accessing metatype information of a bundle containing a metatype resource or providing its own MetaTypeProvider objects.

Calling the OSGi Metatype Service

You can retrieve the OSGi Metatype Service using the techniques defined by the OSGi Framework Specification. It has only one method getMetaTypeInformation(Bundle) which provides metatype information for a specified bundle. This method returns org.osgi.service.metatype.MetaTypeInformation objects which maintains bundle PIDs mapped to the corresponding ObjectClassDefinition objects.

Listing 3. Obtaining the OSGi Metatype Service.

import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.ServiceReference;
import org.osgi.service.metatype.MetaTypeService;


public class MyMetatypeService implements BundleActivator{

  ServiceReference metatyperef = null;
  MetaTypeService mts = null;
  
  public void start(BundleContext bc){

    //Retrieving the OSGi Metatype Service from the OSGi framework
    metatyperef = bc.getServiceReference(MetaTypeService.class.getName());
    mts = (MetaTypeService)bc.getService(metatyperef);
  }
  
  public void stop(BundleContext bc){
    bc.ungetService(metatyperef);
  }
}

Obtaining Object Class Definitions and Attribute Definitions for a Bundle

As mentioned above, through the OSGi Metatype Service can be retrieved MetaTypeInformation objects for each bundle. They can be used to obtain the available PIDs which are mapped to ObjectClassDefinition objects.

The org.osgi.service.metatype.MetaTypeInformation interface extends the org.osgi.service.metatype.MetaTypeProvider interface. The getObjectClassDefinition(String PID, String locale) method of the MetaTypeProvider interface provides access to the ObjectClassDefinition objects for a bundle with a given PID or FPID. The getAttributeDefinitions(int) method of the ObjectClassDefinition interface can be used to retrieve the desired attributes of an object class.

The code example below uses the OSGi Metatype Service, retrieved in Listing 1, and prints out all Object Class Definitions and Attribute Definitions contained in the available bundles.

Listing 4. Retrieving available ObjectClassDefinition and AttributeDefinition objects through the OSGi Metatype Service.

import org.osgi.framework.Bundle;
import java.util.Dictionary;
import java.util.Hashtable;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedService;
import org.osgi.service.metatype.AttributeDefinition;
import org.osgi.service.metatype.MetaTypeProvider;
import org.osgi.service.metatype.ObjectClassDefinition;


public class MyMetaTypeProvider implements BundleActivator, MetaTypeProvider,
         ManagedService{

  private OCD ocd = null;
  AD [] attrDefinitions = new AD[2];
  protected static String PID = "mypid.pid";
  ServiceRegistration sReg = null;
  ServiceRegistration configReg = null;

  // Method inherited from BundleActivator
  public void start(BundleContext bc) throws Exception {

  // Creating an ObjectClassDefinition
  attrDefinitions[0] = new AD("My Attribute Definition", AttributeDefinition.BOOLEAN, 0);
  attrDefinitions[0].setDefaultValue(new String[] { "false" });
  attrDefinitions[1] = new AD("port", AttributeDefinition.INTEGER, 0);
  attrDefinitions[1].setDefaultValue(new String[] { "5983" });
  ocd = new OCD(PID, attrDefinitions);
  ocd.setName("My Example Metatype");

  // Registering the Metatype Provider
  Hashtable regProps = new Hashtable();
  regProps.put(Constants.SERVICE_PID, PID);
  regProps.put("metadata.type", "Config");
  sReg = bc.registerService(MetaTypeProvider.class.getName(), this, regProps);

  // Registering the Managed Service
  Hashtable configProps = new Hashtable();
  configProps.put(Constants.SERVICE_PID, PID);
  configReg = bc.registerService(ManagedService.class.getName(), this, configProps);
  }

  // Method inherited from BundleActivator
  public void stop(BundleContext bc) throws Exception {
    if (sReg != null) {
    sReg.unregister();
    }
    if (configReg != null) {
    configReg.unregister();
    }
    ocd = null;
  }
  // Methods inherited from MetaTypeProvider
  public String[] getLocales() {
  return null;
  }

  public ObjectClassDefinition getObjectClassDefinition(String pid,
    String locale) {
    return ocd;
  }

  // Method inherited from ManagedService
  public void updated(Dictionary props) throws ConfigurationException {
            
                    ...  
  }
}