OSGi Metatype Service

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

Contents:


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:

	  
<?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>
Listing 1.1: An example XML metatype resource.

Note: The ProSyst 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 "ProSyst Metatype Extension" document.

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 {
            
                    ...  
  }
}
		
Listing 1.2: An example Metatype Provider.

Tip: The ProSyst 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 maintain bundle PIDs mapped to the corresponding ObjectClassDefinition objects.

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);
  } 
}	  
	  
Listing 2.1: Obtaining the OSGi Metatype Service.

Obtaining Object Class Definitions and Attribute Definitions for a Bundle

As mentioned before 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.1, and prints out all Object Class Definitions and Attribute Definitions contained in the available bundles.

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.service.metatype.AttributeDefinition;
import org.osgi.service.metatype.MetaTypeInformation;
import org.osgi.service.metatype.MetaTypeService;
import org.osgi.service.metatype.ObjectClassDefinition;


    // Retrieving the OSGi Metatype Service from the OSGi framework
                       ...
				 
    Bundle[] bundles = bc.getBundles();
      for (int i = 0; i < bundles.length; i++) {
	  
        // Getting the org.osgi.service.metatype.MetaTypeInformation object 
        // for all available bundles.
        MetaTypeInformation mti = mts.getMetaTypeInformation(bundles[i]);
		
        // Obtaining the available FPIDs and PIDs for each bundle
        String[] factorypids = mti.getFactoryPids();
        String[] pids = mti.getPids();
		  
          // Retrieving the Object Class Definitions and Attribute Definitions for 
          // bundles with PIDs
          if (pids != null) {
            for (int pid = 0; pid < pids.length; pid++) {
              ObjectClassDefinition ocd = mti.getObjectClassDefinition(pids[pid], null);
              AttributeDefinition[] ads = ocd.getAttributeDefinitions
			  (ObjectClassDefinition.ALL);
			  
                // Printing the available Object Class Definitions and 
                //  Attribute Definitions to the system output
                for (int j = 0; j < ads.length; j++) {
                  System.out.println("AD= " + ads[j].getName() + " OCD= " + ocd.getName());
                }
              }
			  
          // Extracting ObjectClassDefinition and AttributeDefinition objects for bundles 
          // with FPIDs
          }
          if(factorypids != null){
            for (int fpid = 0; fpid < factorypids.length; fpid++) {
              ObjectClassDefinition ocdfactory = mti.getObjectClassDefinition
			  factorypids[fpid], null);
              AttributeDefinition[] adsfactory = ocdfactory.getAttributeDefinitions
			  (ObjectClassDefinition.ALL);
				
               // Printing all Object Class Definitions and Attribute Definitions 
               // for the available bundles to the system output 
               for (int k = 0; k < adsfactory.length; k++) {
                 System.out.println("AD= " + adsfactory[k].getName() 
                  + " OCD= " + ocdfactory.getName());
               }
            }
          }
        }
	  
	                   ...
				   
        
Listing 2.2: Retrieving available ObjectClassDefinition and AttributeDefinition objects through the OSGi Metatype Service.

References


General Description of the Metatype Bundle