[ https://issues.apache.org/jira/browse/FELIX-5939?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Pierre De Rop resolved FELIX-5939. ---------------------------------- Resolution: Fixed committed in revision 1842034. > DM annotations enhancements > --------------------------- > > Key: FELIX-5939 > URL: https://issues.apache.org/jira/browse/FELIX-5939 > Project: Felix > Issue Type: Improvement > Components: Dependency Manager Annotations, Dependency Manager > Runtime > Reporter: Pierre De Rop > Assignee: Pierre De Rop > Priority: Minor > Fix For: org.apache.felix.dependencymanager-r12 > > > Some DM annotations improvements have been done regarding DM Annotation in > this github project: [https://github.com/pderop/dm.enhanced,] and the intent > is to merge the improvements to the felix trunk. > Essentially, the following DM annotations enhancements and modifications have > been done: > * in OSGi R7, declarative service now provides a @ComponentPropertyType > annotation that can be used to defined user defined property type > annotations. Now this annotation is used by other R7 libraries, like jaxrs > whiteboard R7 API. So the DM annotation scanner has been enhanced for the > support of the DS @ComponentPropertyType, allowing you to reuse user defined > annotations from other r7 libraries (whiteboad, etc ...). The dm annotation > plugin has been enhanced by reusing some part of the ds annotation scanner > from bndlib, which is full of reusable useful code which has been applied to > dm (scanning of property types, PREFIX_, etc ...). For consistency api > reasons, a new @PropertyType annotation has also been added to the DM > annotation API: this annotation has the same semantics has the DS > @ComponentPropertyType annotations. > * allow ServiceDependency to auto detect the service type when the > annotation is applied on a collection class field > * removed FactoryComponentAdapterService (some attributes have been added in > the Component annotation in order to declare factory pid components with the > @Component annotation) > * removed some old annotations / attributes. The attributes and annotations > related to metatype have been removed since you can now use the standard > metatype annotations. if users need to use old version, then the previous old > 4.2.1 annotations can be used, because the dm runtime is compatible with old > and new annotations version. > * removed "dereference" attribute in ServiceDependencyAnnotation, because we > can now infer if the service dependency callbacks accepts a ServiceReference > or a ServiceObjects parameter > Since some incompatible changes have been made, the major version of the > annotation bundle has been bumped to 5.0.0. > *User defined property types examples:* > So far, you could define component service properties using DM @Property > annotation, and component configuration could be declared as user defined > interfaces. You can now declare user-defined annotations which can be used to > specify both service properties and component configuration. It means that > instead of declaring service properties using @Property annotation, you can > now use your own annotations (which must be annotated with the new > @PropertyType annotation, or using the standard @ComponentPropertyType > annotation. > For example, let’s assume your write an OSGi r7 jaxrs servlet context which > needs the two following service properties: > {code:java} > osgi.http.whiteboard.context.name > osgi.http.whiteboard.context.path > {code} > Then you can first define your own annotation (but you could also reuse the > default annotations provided by the new jaxrs whiteboard r7 api, from the > org.osgi.service.jaxrs.whiteboard.propertytypes package): > > {code:java} > import org.apache.felix.dependencymanager.annotation.PropertyType; > @PropertyType > @interface ServletContext { > String osgi_http_whiteboard_context_name() default AppServletContext.NAME; > String osgi_http_whiteboard_context_path(); > } > {code} > In the above, the underscore is mapped to ".", and you can apply the above > annotation on top of your component like this: > {code:java} > @Component > @ServletContext(osgi_http_whiteboard_context_path="/game") > public class AppServletContext extends ServletContextHelper { > } > {code} > You can also use configuration admin service in order to override the default > service properties: > {code:java} > @Component > @ServletContext(osgi_http_whiteboard_context_path="/game") > public class AppServletContext extends ServletContextHelper { > @ConfigurationDependency(propagate=true, pid="my.pid") > void updated(ServletContext cnf) { > // if some properties are not present in the configuration, then the > ones used in the > // annotation will be used. > // The configuration admin properties, if defined, will override the > default configurations > // defined in the annotations > } > } > {code} > You can also define multiple property type annotations, and possibly single > valued annotation, like it is the case with standard r7 DS. In this case, you > can use the standard R7 PREFIX_ constants in order to specify the property > prefix, and the property name will be derived from the single valued > annotation (using camel case convention): > {code:java} > @PropertyType > @interface ContextName { > // will map to "osgi.http.whiteboard.context.name" property name > String PREFIX_="osgi.http.whiteboard."; > String value(); > } > > @PropertyType > @interface ContextPath { > // will map to "osgi.http.whiteboard.context.path" property name > String PREFIX_="osgi.http.whiteboard."; > String value(); > } > > @Component > @ContextName(AppServletContext.NAME) > @ContextPath("/game") > public class AppServletContext extends ServletContextHelper { > } > {code} > Now , the following is the same example as above, but also using > configuration admin service in order to override default service properties: > Here, as in OSGi r7 declarative service, you can define a callback method > which accepts as arguments all (or some of) the defined property types: > {code:java} > @Component > @ContextName(AppServletContext.NAME) > @ContextPath("/game") > public class AppServletContext extends ServletContextHelper { > @ConfigurationDependency(propagate=true, pid="my.pid") > void updated(ContextName ctxName, ContextPath ctxPath) { > // if some properties are not present in the configuration, then the > ones used in the annotation > // will be used. > // The configuration admin properties, if defined, will override the > default configurations > // defined in the annotations > } > } > {code} > The following is the same example as above, but this time the configuration > callback can also define a Dictionary in the first argument (in case you want > to also get the raw configuration dictionary: > {code:java} > @Component > @ContextName(AppServletContext.NAME) > @ContextPath("/game") > public class AppServletContext extends ServletContextHelper { > @ConfigurationDependency(propagate=true, pid="my.pid") > void updated(Dictionary<String, Object> rawConfig, ContextName ctxName) { > // if some properties are not present in the configuration, then the > ones used in the annotation > // will be used. > // The configuration admin properties, if defined, will override the > default configurations > // defined in the annotations > } > } > {code} > Empty Marker annotations can also be used: when you define an empty > annotation, it will be mapped to a java.lang.Boolean property type with > Boolean.TRUE value. For example, the following component will be registered > with "osgi.jaxrs.resource" service property with Boolean.TRUE value: > {code:java} > @PropertyType > @interface JaxrsResource { > // will map to "osgi.jaxrs.resource" property name > String PREFIX_="osgi."; > } > > @Component(provides = MyResource.class) > @JaxrsResource > public class MyResource { > @Path(“foo”) > @GET > public void getFoo() { > ... > } > } > {code} > User defined property types can also be applied on factory components, for > example, in the following, the service properties are declared using the > user-defined annotations (they will be overriden from the factory > configuration, if present in the config): > {code:java} > @Component(factoryPid="my.factory.pid") > @ContextName(AppServletContext.NAME) > @ContextPath("/game") > class Hello implements HelloService { > void updated(ContextName ctxName, ContextPath ctxPath) { > // Configure or reconfigure our component. the default service > // properties will be overriden by the factory configuration (if the > // service properties are defined in the config) > } > } > {code} > *Not backward compatible annotation changes:* > This sections describes what has been removed in the annotation api: > * removed FactoryConfigurationAdapterService annotation, which was too > verbose. when you need to define some factory pid component, just reuse the > @Component annotation and declare the new factoryPid/propagate/updated > attributes that have been added in the @Component annotation > * removed PropertyMetadata annotation: it was related to metatypes, but as > of today, osgi metatypes can be defined using standard metatype annotations. > No need to support this anymore. > * removed ResourceAdapterService and ResourceDependency annotations because > it was needed to depend on some classes from the dependency manager API. The > DM Api should be used directly. > * removed the following attributes from the Component annotation: > -- FACTORY_NAME > -- FACTORY_INSTANCE > -- factorySet > -- factoryMethod > These attributes were used to be able to create component instances multiple > times. Now, simply use factoryPid Component attribute and use standard > Configuration Admin in order to instantiate multiple instances of a given > service (using factory configuration). > * removed @PropertyMetaData annotation, which was related to osgi metatype. > now, you can use standard metatype annotations. > Since some incompatible changes have been made, the major version of the > annotation bundle has been bumped to 5.0.0, but the dm runtime is still > compatible with previous annotations. -- This message was sent by Atlassian JIRA (v7.6.3#76005)