NF9 OSGi New Column Callout Factory
From iDempiere en
Feature: OSGi New Column Callout Factory
Goal: Development
Description
- Implement a new column callout factory base class that's backed by Map and Lambda functional object.
- Implement callout annotation and factory base class that scan and register classes with callout annotation.
Usage
With following Callout class:
public class MyTestAmountCallout implements IColumnCallout {
@Override
public String start(Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value, Object oldValue) {
return null;
}
}
Developer can use one of the following approach:
1. At plugin Activator start method, register the callout class.
public void start(BundleContext context) throws Exception {
var factory = Core.getMappedColumnCalloutFactory();
factory.addMapping(MTest.Table_Name, MTest.COLUMNNAME_T_Amount, () -> new MyTestAmountCallout());
}
2. Create an osgi component, at the bind method for the IMappedColumnCalloutFactory service.
public void bindService(IMappedColumnCalloutFactory factory) {
factory.addMapping(MTest.Table_Name, MTest.COLUMNNAME_T_Amount, () -> new MyTestAmountCallout());
}
3. Create a subclass of MappedColumnCalloutFactory, register as IColumnCalloutFactory service (DO NOT register as IMappedColumnCalloutFactory service).
public class MyFactory extends MappedColumnCalloutFactory {
public MyFactory() {
addMapping(MTest.Table_Name, MTest.COLUMNNAME_T_Amount, () -> new MyTestAmountCallout());
}
}
Annotations
- org.adempiere.base.annotation.Callout with tableName and columnName parameter. Use '*' to match any table or column name.
- Usage:
- Annotate your class with org.adempiere.base.annotation.Callout annotation
@Callout(tableName = "AD_InfoWindow", columnName = "AD_Table_ID")
@Callout(tableName = "AD_InfoColumn", columnName = {"AD_Element_ID","AD_Reference_ID"})
public class CalloutInfoWindow implements IColumnCallout {
@Override
public String start(Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value, Object oldValue) {
...
}
}
- Create an OSGi component that extends the AnnotationBasedColumnCalloutFactory class (with service =
IColumnCalloutFactory.class).
- Alternatively, in plugin Activator start method, scan annotated callout classes
public void start(BundleContext context) throws Exception {
//replace org.idempiere.test.callout with package name of your annotated callout classes
Core.getMappedColumnCalloutFactory().scan(context, "org.idempiere.test.callout");
}
- The activator approach above is not 100% safe as Core.getMappedColumnCalloutFactory() can return null if your bundle get activated before the activation of the IMappedColumnCalloutFactory service. The better way is to use @Component, @Reference and @Activator instead.
@Component(immediate = true)
public class MyActivator implements BundleActivator {
@Reference(service = IMappedColumnCalloutFactory.class, cardinality = ReferenceCardinality.MANDATORY)
private IMappedColumnCalloutFactory mappedCalloutFactory;
public MyActivator() {
}
@Override
public void start(BundleContext context) throws Exception {
}
@Override
public void stop(BundleContext context) throws Exception {
}
//activate will only be called after the injection of mappedCalloutFactory reference
@Activate
public void activate(BundleContext context) {
//replace org.idempiere.test.callout with package name of your annotated callout classes
mappedCalloutFactory.scan(context, "org.idempiere.test.callout");
}
}
Technical Info: IDEMPIERE-4690, IDEMPIERE-5015
