NF9 OSGi New Model Factory

From iDempiere en

Feature: OSGi New Model Factory and Annotation

Goal: Development

Developer: Hengsin, Saulo Gil

Description:

  • Implement a new model factory base class that's backed by Map and Lambda functional object.
  • Add org.adempiere.base.Model annotation and factory class that scan and register model classes with Model annotation


Usage:
With following model class:

public class MyTest extends X_Test {
    /**
    * 
    */
    private static final long serialVersionUID = 2010413233032792416L;
    
    public MyTest(Properties ctx, int Test_ID, String trxName) {
	super(ctx, Test_ID, trxName);
    }
    
    public MyTest(Properties ctx, ResultSet rs, String trxName) {
	super(ctx, rs, trxName);
    }				
}

Developer can use one of the following approach:

1. At plugin Activator start method, register the model class.

public void start(BundleContext context) throws Exception {
    var factory = Core.getMappedModelFactory();
    factory.addMapping(MyTest.Table_Name, () -> MyTest.class, 
          (id, trxName) -> new MyTest(Env.getCtx(), id, trxName), 
          (rs, trxName) -> new MyTest(Env.getCtx(), rs, trxName));
}

2. Create an osgi component, at the bind method for the IMappedModelFactory service.

public void bindService(IMappedModelFactory factory) {
    factory.addMapping(MyTest.Table_Name, () -> MyTest.class, 
          (id, trxName) -> new MyTest(Env.getCtx(), id, trxName), 
          (rs, trxName) -> new MyTest(Env.getCtx(), rs, trxName));
}

3. Create a subclass of MappedModelFactory, register as IModelFactory service (DO NOT register as IMappedModelFactory service).

public class MyFactory extends MappedModelFactory {	
    public MyFactory() {
        addMapping(MyTest.Table_Name, () -> MyTest.class, 
            (id, trxName) -> new MyTest(Env.getCtx(), id, trxName), 
            (rs, trxName) -> new MyTest(Env.getCtx(), rs, trxName));
    }		
}

4. IDEMPIERE-5004 added scan(BundleContext context, String... packages) method to IMappedModelFactory and MappedModelFactory. Developer can call that at plugin Activator start method to register model classes with org.adempiere.base.Model annotation.

  public void start(BundleContext context) throws Exception {
      //replace org.idempiere.test.model.annotated with the package name of your model classes
      Core.getMappedModelFactory().scan(context, "org.idempiere.test.model.annotated");
  }


Annotation

1. org.adempiere.base.Model annotation with table attribute.

2. org.adempiere.base.AnnotationBasedModelFactory, new IModelFactory service that scan and register core model classes with Model annotation. Developer only have to annotate X_* model classes as the service will looks for the lowest subclass that extend annotated X_* model classes.

3. Model class generator is modify to generate X_* model class with Model annotation

4. Plugin should either use method 4 above or create OSGi component that extend AnnotationBasedModelFactory class (usually with @Component(immediate = true, service = IModelFactory.class, property = "service.ranking:Integer=1") component annotation).

 @org.adempiere.base.Model(table="C_BPartner")
 public class X_C_BPartner extends PO implements I_C_BPartner, I_Persistent
 {
     ...
 }


Technical Info:
IDEMPIERE-4675, IDEMPIERE-5004, IDEMPIERE-4842

Cookies help us deliver our services. By using our services, you agree to our use of cookies.