IDEMPIERE-4675 Add model factory base class backed by Map and Lambda … (#555)
- added interface and default mapped model factory service - added unit test for default mapped model factory service
This commit is contained in:
parent
4009c9c8ca
commit
0f263f1c79
|
@ -25,6 +25,11 @@
|
|||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ds.core.builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
classpath=true
|
||||
dsVersion=V1_3
|
||||
eclipse.preferences.version=1
|
||||
enabled=true
|
||||
generateBundleActivationPolicyLazy=true
|
||||
path=OSGI-INF
|
||||
validationErrorLevel=error
|
||||
validationErrorLevel.missingImplicitUnbindMethod=error
|
|
@ -90,6 +90,7 @@ Import-Package: com.google.zxing,
|
|||
org.osgi.framework,
|
||||
org.osgi.service.cm;version="1.3.0",
|
||||
org.osgi.service.component;version="1.1.0",
|
||||
org.osgi.service.component.annotations;version="1.3.0",
|
||||
org.osgi.service.component.runtime;version="1.3.0",
|
||||
org.osgi.service.component.runtime.dto;version="1.3.0",
|
||||
org.osgi.service.event;version="1.2.0",
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="org.idempiere.model.MappedModelFactory">
|
||||
<property name="service.ranking" type="Integer" value="1"/>
|
||||
<service>
|
||||
<provide interface="org.adempiere.base.IModelFactory"/>
|
||||
<provide interface="org.idempiere.model.IMappedModelFactory"/>
|
||||
</service>
|
||||
<implementation class="org.idempiere.model.MappedModelFactory"/>
|
||||
</scr:component>
|
|
@ -55,6 +55,7 @@ import org.idempiere.distributed.IMessageService;
|
|||
import org.idempiere.fa.service.api.DepreciationFactoryLookupDTO;
|
||||
import org.idempiere.fa.service.api.IDepreciationMethod;
|
||||
import org.idempiere.fa.service.api.IDepreciationMethodFactory;
|
||||
import org.idempiere.model.IMappedModelFactory;
|
||||
|
||||
/**
|
||||
* This is a facade class for the Service Locator.
|
||||
|
@ -924,4 +925,24 @@ public class Core {
|
|||
return ids;
|
||||
}
|
||||
|
||||
private static IServiceReferenceHolder<IMappedModelFactory> s_mappedModelFactoryReference = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @return {@link IMappedModelFactory}
|
||||
*/
|
||||
public static IMappedModelFactory getMappedModelFactory(){
|
||||
IMappedModelFactory modelFactoryService = null;
|
||||
if (s_mappedModelFactoryReference != null) {
|
||||
modelFactoryService = s_mappedModelFactoryReference.getService();
|
||||
if (modelFactoryService != null)
|
||||
return modelFactoryService;
|
||||
}
|
||||
IServiceReferenceHolder<IMappedModelFactory> serviceReference = Service.locator().locate(IMappedModelFactory.class).getServiceReference();
|
||||
if (serviceReference != null) {
|
||||
modelFactoryService = serviceReference.getService();
|
||||
s_mappedModelFactoryReference = serviceReference;
|
||||
}
|
||||
return modelFactoryService;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/***********************************************************************
|
||||
* This file is part of iDempiere ERP Open Source *
|
||||
* http://www.idempiere.org *
|
||||
* *
|
||||
* Copyright (C) Contributors *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||
* MA 02110-1301, USA. *
|
||||
* *
|
||||
* Contributors: *
|
||||
* - hengsin *
|
||||
**********************************************************************/
|
||||
package org.idempiere.model;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.compiere.model.PO;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
public interface IMappedModelFactory {
|
||||
|
||||
/**
|
||||
* add table name to class mapping
|
||||
* @param tableName
|
||||
* @param classSupplier
|
||||
* @param recordIdFunction
|
||||
* @param resultSetFunction
|
||||
*/
|
||||
void addMapping(String tableName, Supplier<Class<?>> classSupplier,
|
||||
BiFunction<Integer, String, ? extends PO> recordIdFunction,
|
||||
BiFunction<ResultSet, String, ? extends PO> resultSetFunction);
|
||||
|
||||
/**
|
||||
* remove table name to class mapping
|
||||
* @param tableName
|
||||
*/
|
||||
void removeMapping(String tableName);
|
||||
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/***********************************************************************
|
||||
* This file is part of iDempiere ERP Open Source *
|
||||
* http://www.idempiere.org *
|
||||
* *
|
||||
* Copyright (C) Contributors *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||
* MA 02110-1301, USA. *
|
||||
* *
|
||||
* Contributors: *
|
||||
* - hengsin *
|
||||
**********************************************************************/
|
||||
package org.idempiere.model;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.adempiere.base.IModelFactory;
|
||||
import org.compiere.model.PO;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
|
||||
/**
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
@Component(name = "org.idempiere.model.MappedModelFactory",
|
||||
immediate = true,
|
||||
service = {IModelFactory.class, IMappedModelFactory.class},
|
||||
property = {"service.ranking:Integer=1"})
|
||||
public class MappedModelFactory implements IModelFactory, IMappedModelFactory {
|
||||
|
||||
private final ConcurrentHashMap<String, Supplier<Class<?>>> classMap = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<String, BiFunction<Integer, String, ? extends PO>> recordIdMap = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<String, BiFunction<ResultSet, String, ? extends PO>> resultSetMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* default constructor
|
||||
*/
|
||||
public MappedModelFactory() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getClass(String tableName) {
|
||||
var supplier = classMap.get(tableName);
|
||||
return supplier != null ? supplier.get() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PO getPO(String tableName, int Record_ID, String trxName) {
|
||||
var function = recordIdMap.get(tableName);
|
||||
return function != null ? function.apply(Record_ID, trxName) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PO getPO(String tableName, ResultSet rs, String trxName) {
|
||||
var function = resultSetMap.get(tableName);
|
||||
return function != null ? function.apply(rs, trxName) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addMapping(String tableName, Supplier<Class<?>> classSupplier, BiFunction<Integer, String, ? extends PO> recordIdFunction,
|
||||
BiFunction<ResultSet, String, ? extends PO> resultSetFunction) {
|
||||
classMap.put(tableName, classSupplier);
|
||||
recordIdMap.put(tableName, recordIdFunction);
|
||||
resultSetMap.put(tableName, resultSetFunction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeMapping(String tableName) {
|
||||
classMap.remove(tableName);
|
||||
recordIdMap.remove(tableName);
|
||||
resultSetMap.remove(tableName);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
/***********************************************************************
|
||||
* This file is part of iDempiere ERP Open Source *
|
||||
* http://www.idempiere.org *
|
||||
* *
|
||||
* Copyright (C) Contributors *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||
* MA 02110-1301, USA. *
|
||||
* *
|
||||
* Contributors: *
|
||||
* - hengsin *
|
||||
**********************************************************************/
|
||||
package org.idempiere.test.model;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Dictionary;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.adempiere.base.Core;
|
||||
import org.adempiere.base.IModelFactory;
|
||||
import org.compiere.model.MTable;
|
||||
import org.compiere.model.PO;
|
||||
import org.compiere.model.X_Test;
|
||||
import org.compiere.util.CacheMgt;
|
||||
import org.compiere.util.Env;
|
||||
import org.idempiere.model.IMappedModelFactory;
|
||||
import org.idempiere.model.MappedModelFactory;
|
||||
import org.idempiere.test.AbstractTestCase;
|
||||
import org.idempiere.test.TestActivator;
|
||||
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
|
||||
import org.junit.jupiter.api.Order;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestMethodOrder;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
/**
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
@TestMethodOrder(OrderAnnotation.class)
|
||||
public class MappedModelFactoryTest extends AbstractTestCase {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public MappedModelFactoryTest() {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(1)
|
||||
public void testDefaultMappedModelFactory() {
|
||||
IMappedModelFactory mappedFactory = Core.getMappedModelFactory();
|
||||
mappedFactory.addMapping(MyTest.Table_Name, () -> MyTest.class, (id, trxName) -> new MyTest(Env.getCtx(), id, trxName),
|
||||
(rs, trxName) -> new MyTest(Env.getCtx(), rs, trxName));
|
||||
PO po = MTable.get(MyTest.Table_ID).getPO(0, getTrxName());
|
||||
assertTrue(po instanceof MyTest, "PO not instanceof MyTest. PO.className="+po.getClass().getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(2)
|
||||
public void testCustomMappedModelFactory() {
|
||||
BundleContext bc = TestActivator.context;
|
||||
Dictionary<String, Object> properties = new Hashtable<String, Object>();
|
||||
properties.put("service.ranking", Integer.valueOf(2));
|
||||
bc.registerService(IModelFactory.class, new MyFactory(), properties);
|
||||
CacheMgt.get().reset();
|
||||
PO po = MTable.get(MyTest2.Table_ID).getPO(0, getTrxName());
|
||||
assertTrue(po instanceof MyTest2, "PO not instanceof MyTest2. PO.className="+po.getClass().getName());
|
||||
}
|
||||
|
||||
private final static class MyFactory extends MappedModelFactory {
|
||||
|
||||
public MyFactory() {
|
||||
addMapping(MyTest2.Table_Name, () -> MyTest2.class, (id, trxName) -> new MyTest2(Env.getCtx(), id, trxName),
|
||||
(rs, trxName) -> new MyTest2(Env.getCtx(), rs, trxName));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final static 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);
|
||||
}
|
||||
}
|
||||
|
||||
private final static class MyTest2 extends X_Test {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 2010413233032792416L;
|
||||
|
||||
public MyTest2(Properties ctx, int Test_ID, String trxName) {
|
||||
super(ctx, Test_ID, trxName);
|
||||
}
|
||||
|
||||
public MyTest2(Properties ctx, ResultSet rs, String trxName) {
|
||||
super(ctx, rs, trxName);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue