// /com/sourcedcode/services/impl/MyserviceImpl.java
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.metatype.annotations.Designate;
@Component(service = MyService.class, immediate = true)
@Designate(ocd = SourcedCodeSiteSettingsConfig.class)
public class MyserviceImpl extends MyService {
@Activate
protected void activate(SourcedCodeSiteSettingsConfig config) {
// do something
// String name = config.name();
}
}
The “ocd” property must be set with a configuration interface class that is annotated with @ObjectClassDefinition; the annotated interface class can be an imported Java interface class or inner Java interface class.
Once the @Designate annotation on the OSGi Component’s class and the @ObjectClassDefinition configuration interface are configured, the OSGi Component(s) will have enabled the configuration successfully; you should be able to find the configuration in the OSGI Apache Felix Console, under http://localhost:4502/system/console/configMgr.
What is the @ObjectClassDefinition annotation?
The configuration interface is annotated with @ObjectClassDefinition where properties can be passed into the @ObjectClassDefinition annotation. The most common properties are @ObjectClassDefinition(name=””, description=””). The “name” property will be used as the title of the configuration popup within the OSGI Felix console, while the description property is used for the “description” of the popup.
// Example:
package com.sourcedcode.core.services;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
@ObjectClassDefinition(name = "SourcedCode - Site Settings Configuration",
description = "dialog description"
)
public @interface SourcedCodeSiteSettingsConfigExample {
// config1 @AttributeDefinition()
// config2 @AttributeDefinition()
// config3 @AttributeDefinition()
}
What is the @AttributeDefinition annotation?
Declaration of the @AttributeDefinition annotations defines each configuration by identifying the type, the configuration reference name, config name, and description.
package com.sourcedcode.core.services;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.AttributeType;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
@ObjectClassDefinition(name = "SourcedCode - Site Settings Configuration",
description = "dialog description")
public @interface SourcedCodeSiteSettingsConfigExample {
@AttributeDefinition(
name = "String[] Label",
description = "String[] Config Example Description",
type = AttributeType.STRING)
String[] config_string_array_example() default {"item1", "item2"};
// config2 @AttributeDefinition()
// config3 @AttributeDefinition()
}
1. Imported Class – Defining OSGI Component’s Configuration with Configuration Interface
The title of this section speaks for itself. The examples below "Step A" example provides a sample code of a configuration interface class that is prepared to be imported OSGI Service Component, indicated in "Step B". This class has one responsibility, and its to provide the definition of the OSGI Component’s configuration interface.
Step A. Defining the annotated Configuration Interface
Isolated configuration interface class that prepared to be imported and referenced by the OSGI Service Component.
package com.sourcedcode.core.services;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.AttributeType;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
import org.osgi.service.metatype.annotations.Option;
@ObjectClassDefinition(name = "SourcedCode - Site Settings Configuration",
description = "dialog description")
public @interface SourcedCodeSiteSettingsConfig {
@AttributeDefinition(
name = "String Label",
description = "String Config Example Description",
type = AttributeType.STRING)
String config_string_example() default "Default String";
@AttributeDefinition(
name = "String[] Label",
description = "String[] Config Example Description",
type = AttributeType.STRING)
String[] config_string_array_example() default {"item1", "item2"};
@AttributeDefinition(
name = "Long Label",
description = "Long Config Example Description",
type = AttributeType.LONG)
long config_long_example() default 0L;
@AttributeDefinition(
name = "int Label",
description = "innt Config Example Description",
type = AttributeType.INTEGER)
int config_number_example() default 0;
@AttributeDefinition(
name = "Short Label",
description = "Short Config Example Description",
type = AttributeType.SHORT)
short config_short_example() default 0;
@AttributeDefinition(
name = "Char Label",
description = "Char Config Example Description",
type = AttributeType.CHARACTER)
char config_char_example() default 0;
@AttributeDefinition(
name = "Byte Label",
description = "Byte Config Example Description",
type = AttributeType.BYTE)
byte config_byte_example() default 0;
@AttributeDefinition(
name = "Double Label",
description = "Double Config Example Description",
type = AttributeType.DOUBLE)
double config_double_example() default 0;
@AttributeDefinition(
name = "Float Label",
description = "Float Config Example Description",
type = AttributeType.FLOAT)
float config_float_example() default 0;
@AttributeDefinition(
name = "Boolean Label",
description = "Boolean Config Example Description",
type = AttributeType.BOOLEAN)
boolean config_boolean_example() default true;
@AttributeDefinition(
name = "Password Label",
description = "Password Config Example Description",
type = AttributeType.PASSWORD)
String config_password_config_example() default "";
@AttributeDefinition(
name = "Dropdown Label",
description = "Dropdown Config Example Description",
options = {
@Option(label = "PRODUCTION", value = "PRODUCTION"),
@Option(label = "STAGING", value = "STAGING"),
@Option(label = "UAT", value = "UAT"),
@Option(label = "QA", value = "QA"),
@Option(label = "DEVELOP", value = "DEVELOP")
}
)
String config_dropdown_example() default "DEVELOP";
}
Step B. Consuming the Configuration Interface by Imported Class
To use the configuration interface within our OSGI service component, we would need to annotation our service class with @Designate, with the OCD param pointing to the imported configuration interface class. Next, it would be as simple as setting up the initial @Activate method.
package com.sourcedcode.core.services;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.metatype.annotations.Designate;
import com.sourcedcode.core.services.SourcedCodeSiteSettingsConfig;
@Component(service = SourcedCodeSiteSettingsService.class, immediate = true)
@Designate(ocd = SourcedCodeSiteSettingsConfig.class)
public class SourcedCodeSiteSettingsService {
private String config_string_example;
private String[] config_string_array_example;
private long config_long_example;
private int config_number_example;
private short config_short_example;
private char config_char_example;
private byte config_byte_example;
private double config_double_example;
private float config_float_example;
private Boolean config_boolean_example;
private String config_password_getConfig_example;
private String config_dropdown_example;
@Activate
protected void activate(SourcedCodeSiteSettingsConfig config) {
this.config_string_example = config.config_string_example();
this.config_string_array_example = config.config_string_array_example();
this.config_long_example = config.config_long_example();
this.config_number_example = config.config_number_example();
this.config_short_example = config.config_short_example();
this.config_char_example = config.config_char_example();
this.config_byte_example = config.config_byte_example();
this.config_double_example = config.config_double_example();
this.config_float_example = config.config_float_example();
this.config_boolean_example = config.config_boolean_example();
this.config_password_getConfig_example = config.config_password_config_example();
this.config_dropdown_example = config.config_dropdown_example();
}
}
Outcome Explained:
The outcome of the OSGI Service and Configuration will result in an editable configuration within the OSGI Apache Felix Console.
2. Inner Class – Defining OSGI Component’s Configuration with Configuration Interface
You can also define the annotated @ObjectClassDefinition interface as an inner class as shown below. To use the inner class configuration interface within our OSGI service, we would need to annotation our service class with @Designate, with the OCD param pointing to the inner interface class. Next, it would be as simple as setting up the initial @Activate method.
package com.sourcedcode.core.services.impl;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.metatype.annotations.*;
@Component(service = SourcedCodeSiteSettingsServiceInlineExample.class, immediate = true)
@Designate(ocd = SourcedCodeSiteSettingsServiceInlineExample.SourcedCodeSiteSettingsConfig.class)
public class SourcedCodeSiteSettingsServiceInlineExample {
@ObjectClassDefinition(name = "SourcedCode - Site Settings Configuration",
description = "dialog description")
protected @interface SourcedCodeSiteSettingsConfig {
@AttributeDefinition(
name = "String Label",
description = "String Config Example Description",
type = AttributeType.STRING)
String config_string_example() default "Default String";
@AttributeDefinition(
name = "String[] Label",
description = "String[] Config Example Description",
type = AttributeType.STRING)
String[] config_string_array_example() default {"item1", "item2"};
@AttributeDefinition(
name = "Long Label",
description = "Long Config Example Description",
type = AttributeType.LONG)
long config_long_example() default 0L;
}
@Activate
protected void activate(SourcedCodeSiteSettingsConfig config) {
}
}
NOTES:
@AttributeDefinitions are the underlying formatting of how each OSGI configuration interface are put together.
No comments:
Post a Comment
If you have any doubts or questions, please let us know.