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