From 5e60c443d2747b2c4d66e743efc6ebd31455556a Mon Sep 17 00:00:00 2001 From: hengsin Date: Tue, 16 Feb 2021 18:24:31 +0800 Subject: [PATCH] IDEMPIERE-4704 Add base interface and class that uses generic type and lambda function for osgi factory that create new instance by class name or a string key (#585) --- .../adempiere/base/IMappedByNameFactory.java | 65 ++ .../adempiere/base/MappedByNameFactory.java | 60 ++ .../process/IMappedProcessFactory.java | 19 +- .../process/MappedProcessFactory.java | 21 +- .../test/base/MappedByNameFactoryTest.java | 597 ++++++++++++++++++ .../MappedProcessFactoryTest.java | 4 +- 6 files changed, 730 insertions(+), 36 deletions(-) create mode 100644 org.adempiere.base/src/org/adempiere/base/IMappedByNameFactory.java create mode 100644 org.adempiere.base/src/org/adempiere/base/MappedByNameFactory.java create mode 100644 org.idempiere.test/src/org/idempiere/test/base/MappedByNameFactoryTest.java rename org.idempiere.test/src/org/idempiere/test/{model => base}/MappedProcessFactoryTest.java (97%) diff --git a/org.adempiere.base/src/org/adempiere/base/IMappedByNameFactory.java b/org.adempiere.base/src/org/adempiere/base/IMappedByNameFactory.java new file mode 100644 index 0000000000..19150bdd9b --- /dev/null +++ b/org.adempiere.base/src/org/adempiere/base/IMappedByNameFactory.java @@ -0,0 +1,65 @@ +/*********************************************************************** + * 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.adempiere.base; + +import java.util.function.Supplier; + +/** + * Generic base interface for factory service that provide name/classname to instance mapping service + * @author hengsin + * + * @param + */ +public interface IMappedByNameFactory { + /** + * add name to class mapping + * @param name + * @param supplier + */ + public void addMapping(String name, Supplier supplier); + + /** + * remove name to class mapping + * @param name + */ + public void removeMapping(String name); + + /** + * + * @param name + * @return {@link Supplier} + */ + public Supplier getSupplier(String name); + + /** + * + * @param name + * @return new instance of T (if there are register supplier for name) + */ + public default T newInstance(String name) { + var supplier = getSupplier(name); + return supplier != null ? supplier.get() : null; + } +} diff --git a/org.adempiere.base/src/org/adempiere/base/MappedByNameFactory.java b/org.adempiere.base/src/org/adempiere/base/MappedByNameFactory.java new file mode 100644 index 0000000000..e4182ad281 --- /dev/null +++ b/org.adempiere.base/src/org/adempiere/base/MappedByNameFactory.java @@ -0,0 +1,60 @@ +/*********************************************************************** + * 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.adempiere.base; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Supplier; + +/** + * Provide simple name/class name mapping through register lambda supplier object + * @author hengsin + * + * @param + */ +public class MappedByNameFactory implements IMappedByNameFactory { + + private final ConcurrentHashMap> supplierMap = new ConcurrentHashMap<>(); + + /** + * default constructor + */ + public MappedByNameFactory() { + } + + @Override + public void addMapping(String name, Supplier Supplier) { + supplierMap.put(name, Supplier); + } + + @Override + public void removeMapping(String name) { + supplierMap.remove(name); + } + + @Override + public Supplier getSupplier(String name) { + return supplierMap.get(name); + } +} diff --git a/org.adempiere.base/src/org/idempiere/process/IMappedProcessFactory.java b/org.adempiere.base/src/org/idempiere/process/IMappedProcessFactory.java index 0486b2cea0..bff756822c 100644 --- a/org.adempiere.base/src/org/idempiere/process/IMappedProcessFactory.java +++ b/org.adempiere.base/src/org/idempiere/process/IMappedProcessFactory.java @@ -24,8 +24,7 @@ **********************************************************************/ package org.idempiere.process; -import java.util.function.Supplier; - +import org.adempiere.base.IMappedByNameFactory; import org.compiere.process.ProcessCall; /** @@ -33,19 +32,5 @@ import org.compiere.process.ProcessCall; * @author hengsin * */ -public interface IMappedProcessFactory { - - /** - * add name to class mapping - * @param name - * @param processSupplier - */ - void addMapping(String name, Supplier processSupplier); - - /** - * remove name to class mapping - * @param name - */ - void removeMapping(String name); - +public interface IMappedProcessFactory extends IMappedByNameFactory { } \ No newline at end of file diff --git a/org.adempiere.base/src/org/idempiere/process/MappedProcessFactory.java b/org.adempiere.base/src/org/idempiere/process/MappedProcessFactory.java index e5384f60ba..7a9d73b049 100644 --- a/org.adempiere.base/src/org/idempiere/process/MappedProcessFactory.java +++ b/org.adempiere.base/src/org/idempiere/process/MappedProcessFactory.java @@ -24,10 +24,8 @@ **********************************************************************/ package org.idempiere.process; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Supplier; - import org.adempiere.base.IProcessFactory; +import org.adempiere.base.MappedByNameFactory; import org.compiere.process.ProcessCall; import org.osgi.service.component.annotations.Component; @@ -39,10 +37,8 @@ import org.osgi.service.component.annotations.Component; immediate = true, service = {IProcessFactory.class, IMappedProcessFactory.class}, property = {"service.ranking:Integer=1"}) -public class MappedProcessFactory implements IProcessFactory, IMappedProcessFactory { +public class MappedProcessFactory extends MappedByNameFactory implements IProcessFactory, IMappedProcessFactory { - private final ConcurrentHashMap> processMap = new ConcurrentHashMap<>(); - /** * default constructor */ @@ -51,17 +47,6 @@ public class MappedProcessFactory implements IProcessFactory, IMappedProcessFact @Override public ProcessCall newProcessInstance(String className) { - var supplier = processMap.get(className); - return supplier != null ? supplier.get() : null; - } - - @Override - public void addMapping(String name, Supplier processSupplier) { - processMap.put(name, processSupplier); - } - - @Override - public void removeMapping(String name) { - processMap.remove(name); + return newInstance(className); } } diff --git a/org.idempiere.test/src/org/idempiere/test/base/MappedByNameFactoryTest.java b/org.idempiere.test/src/org/idempiere/test/base/MappedByNameFactoryTest.java new file mode 100644 index 0000000000..679232e05f --- /dev/null +++ b/org.idempiere.test/src/org/idempiere/test/base/MappedByNameFactoryTest.java @@ -0,0 +1,597 @@ +/*********************************************************************** + * 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.base; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.math.BigDecimal; +import java.sql.Timestamp; +import java.util.Dictionary; +import java.util.Hashtable; +import java.util.Properties; + +import org.adempiere.base.Core; +import org.adempiere.base.IAddressValidationFactory; +import org.adempiere.base.IBankStatementLoaderFactory; +import org.adempiere.base.IBankStatementMatcherFactory; +import org.adempiere.base.IModelValidatorFactory; +import org.adempiere.base.IPaymentExporterFactory; +import org.adempiere.base.IPaymentProcessorFactory; +import org.adempiere.base.IReplenishFactory; +import org.adempiere.base.IShipmentProcessorFactory; +import org.adempiere.base.ITaxProviderFactory; +import org.adempiere.base.MappedByNameFactory; +import org.adempiere.model.IAddressValidation; +import org.adempiere.model.IShipmentProcessor; +import org.adempiere.model.ITaxProvider; +import org.adempiere.model.MFreightShipmentProcessor; +import org.adempiere.model.MShipperFacade; +import org.compiere.impexp.BankStatementLoaderInterface; +import org.compiere.impexp.BankStatementMatchInfo; +import org.compiere.impexp.BankStatementMatcherInterface; +import org.compiere.model.MAddressTransaction; +import org.compiere.model.MAddressValidation; +import org.compiere.model.MBankAccountProcessor; +import org.compiere.model.MBankStatementLine; +import org.compiere.model.MBankStatementLoader; +import org.compiere.model.MClient; +import org.compiere.model.MShipper; +import org.compiere.model.MTable; +import org.compiere.model.MTaxProvider; +import org.compiere.model.MWarehouse; +import org.compiere.model.ModelValidationEngine; +import org.compiere.model.ModelValidator; +import org.compiere.model.PO; +import org.compiere.model.PaymentInterface; +import org.compiere.model.PaymentProcessor; +import org.compiere.model.Query; +import org.compiere.model.StandardTaxProvider; +import org.compiere.model.X_C_AddressValidationCfg; +import org.compiere.model.X_C_TaxProviderCfg; +import org.compiere.model.X_I_BankStatement; +import org.compiere.model.X_T_Replenish; +import org.compiere.util.Env; +import org.compiere.util.GenericPaymentExport; +import org.compiere.util.PaymentExport; +import org.compiere.util.ReplenishInterface; +import org.idempiere.fa.service.api.DepreciationDTO; +import org.idempiere.fa.service.api.DepreciationFactoryLookupDTO; +import org.idempiere.fa.service.api.IDepreciationMethod; +import org.idempiere.fa.service.api.IDepreciationMethodFactory; +import org.idempiere.test.AbstractTestCase; +import org.idempiere.test.TestActivator; +import org.junit.jupiter.api.Test; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; + +/** + * + * @author hengsin + * + */ +public class MappedByNameFactoryTest extends AbstractTestCase { + + public MappedByNameFactoryTest() { + } + + private final static class MyModelValidator implements ModelValidator { + @Override + public void initialize(ModelValidationEngine engine, MClient client) { + } + + @Override + public int getAD_Client_ID() { + return 0; + } + + @Override + public String login(int AD_Org_ID, int AD_Role_ID, int AD_User_ID) { + return null; + } + + @Override + public String modelChange(PO po, int type) throws Exception { + return null; + } + + @Override + public String docValidate(PO po, int timing) { + return null; + } + } + + private final static class MyModelValidatorFactory extends MappedByNameFactory implements IModelValidatorFactory { + + public MyModelValidatorFactory() { + addMapping(MyModelValidator.class.getName(), () -> new MyModelValidator()); + } + + @Override + public ModelValidator newModelValidatorInstance(String className) { + return newInstance(className); + } + } + + @Test + public void testModelValidatorFactory() { + //simulate osgi component service + BundleContext bc = TestActivator.context; + Dictionary properties = new Hashtable(); + properties.put("service.ranking", Integer.valueOf(1)); + bc.registerService(IModelValidatorFactory.class, new MyModelValidatorFactory(), properties); + + var validator = Core.getModelValidator(MyModelValidator.class.getName()); + assertNotNull(validator); + assertTrue(validator instanceof MyModelValidator); + } + + private final static class MyPaymentProcessor extends PaymentProcessor { + @Override + public boolean processCC() throws IllegalArgumentException { + return false; + } + + @Override + public boolean isProcessedOK() { + return false; + } + } + + private final static class MyPaymentProcessFactory extends MappedByNameFactory implements IPaymentProcessorFactory { + public MyPaymentProcessFactory() { + addMapping("org.compiere.model.PP_PayFlowPro", () -> new MyPaymentProcessor()); + } + + @Override + public PaymentProcessor newPaymentProcessorInstance(String className) { + return newInstance(className); + } + + } + + @Test + public void testPaymentProcessorFactory() { + //simulate osgi component service + BundleContext bc = TestActivator.context; + Dictionary properties = new Hashtable(); + properties.put("service.ranking", Integer.valueOf(1)); + ServiceRegistration registration = bc.registerService(IPaymentProcessorFactory.class, new MyPaymentProcessFactory(), properties); + + PaymentInterface mp = null; + MBankAccountProcessor mbap; + Query query = new Query(Env.getCtx(), MBankAccountProcessor.Table_Name, MTable.getUUIDColumnName(MBankAccountProcessor.Table_Name)+"=?", null); + mbap = query.setParameters("f4a64026-bf68-4c8c-b238-8cdf006aae04").first(); + var pp = Core.getPaymentProcessor(mbap, mp); + assertNotNull(pp); + assertTrue(pp instanceof MyPaymentProcessor); + + registration.unregister(); + } + + private final static class MyBankStatementLoader implements BankStatementLoaderInterface { + + @Override + public boolean init(MBankStatementLoader controller) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isValid() { + return false; + } + + @Override + public boolean loadLines() { + return false; + } + + @Override + public String getLastErrorMessage() { + return null; + } + + @Override + public String getLastErrorDescription() { + return null; + } + + @Override + public Timestamp getDateLastRun() { + return null; + } + + @Override + public String getRoutingNo() { + return null; + } + + @Override + public String getBankAccountNo() { + return null; + } + + @Override + public String getIBAN() { + return null; + } + + @Override + public String getStatementReference() { + return null; + } + + @Override + public Timestamp getStatementDate() { + return null; + } + + @Override + public String getTrxID() { + return null; + } + + @Override + public String getReference() { + return null; + } + + @Override + public String getCheckNo() { + return null; + } + + @Override + public String getPayeeName() { + return null; + } + + @Override + public String getPayeeAccountNo() { + return null; + } + + @Override + public Timestamp getStatementLineDate() { + return null; + } + + @Override + public Timestamp getValutaDate() { + return null; + } + + @Override + public String getTrxType() { + return null; + } + + @Override + public boolean getIsReversal() { + return false; + } + + @Override + public String getCurrency() { + return null; + } + + @Override + public BigDecimal getStmtAmt() { + return null; + } + + @Override + public BigDecimal getTrxAmt() { + return null; + } + + @Override + public BigDecimal getInterestAmt() { + return null; + } + + @Override + public String getMemo() { + return null; + } + + @Override + public String getChargeName() { + return null; + } + + @Override + public BigDecimal getChargeAmt() { + return null; + } + + } + + private final static class MyBankStatementLoaderFactory extends MappedByNameFactory implements IBankStatementLoaderFactory { + + public MyBankStatementLoaderFactory() { + addMapping(MyBankStatementLoader.class.getName(), () -> new MyBankStatementLoader()); + } + + @Override + public BankStatementLoaderInterface newBankStatementLoaderInstance(String className) { + return newInstance(className); + } + } + + @Test + public void testBankStatementLoaderFactory() { + //simulate osgi component service + BundleContext bc = TestActivator.context; + Dictionary properties = new Hashtable(); + properties.put("service.ranking", Integer.valueOf(1)); + bc.registerService(IBankStatementLoaderFactory.class, new MyBankStatementLoaderFactory(), properties); + var loader = Core.getBankStatementLoader(MyBankStatementLoader.class.getName()); + assertNotNull(loader); + assertTrue(loader instanceof MyBankStatementLoader); + } + + private static final class MyBankStatementMatcher implements BankStatementMatcherInterface { + @Override + public BankStatementMatchInfo findMatch(MBankStatementLine bsl) { + return null; + } + + @Override + public BankStatementMatchInfo findMatch(X_I_BankStatement ibs) { + return null; + } + } + + private final static class MyBankStatementMatcherFactory extends MappedByNameFactory implements IBankStatementMatcherFactory { + public MyBankStatementMatcherFactory() { + addMapping(MyBankStatementMatcher.class.getName(), () -> new MyBankStatementMatcher()); + } + + @Override + public BankStatementMatcherInterface newBankStatementMatcherInstance(String className) { + return newInstance(className); + } + } + + @Test + public void testBankStatementMatcherFactory() { + //simulate osgi component service + BundleContext bc = TestActivator.context; + Dictionary properties = new Hashtable(); + properties.put("service.ranking", Integer.valueOf(1)); + bc.registerService(IBankStatementMatcherFactory.class, new MyBankStatementMatcherFactory(), properties); + var loader = Core.getBankStatementMatcher(MyBankStatementMatcher.class.getName()); + assertNotNull(loader); + assertTrue(loader instanceof MyBankStatementMatcher); + } + + private final static class MyShipmentProcessor extends MFreightShipmentProcessor { + } + + private final static class MyShipmentProcessorFactory extends MappedByNameFactory implements IShipmentProcessorFactory { + public MyShipmentProcessorFactory() { + addMapping("org.adempiere.model.MFreightShipmentProcessor", () -> new MyShipmentProcessor()); + } + + @Override + public IShipmentProcessor newShipmentProcessorInstance(String className) { + return newInstance(className); + } + } + + @Test + public void testShipmentProcessorFactory() { + //simulate osgi component service + BundleContext bc = TestActivator.context; + Dictionary properties = new Hashtable(); + properties.put("service.ranking", Integer.valueOf(1)); + ServiceRegistration sr = bc.registerService(IShipmentProcessorFactory.class, new MyShipmentProcessorFactory(), properties); + MShipper shipper = new MShipper(Env.getCtx(), 100, getTrxName()); + MShipperFacade sf = new MShipperFacade(shipper); + var loader = Core.getShipmentProcessor(sf); + assertNotNull(loader); + assertTrue(loader instanceof MyShipmentProcessor); + sr.unregister(); + } + + private final static class MyAddressValidation implements IAddressValidation { + @Override + public boolean onlineValidate(Properties ctx, MAddressTransaction addressTransaction, String trxName) { + return false; + } + } + + private final static class MyAddressValidationFactory extends MappedByNameFactory implements IAddressValidationFactory { + public MyAddressValidationFactory() { + addMapping(MyAddressValidation.class.getName(), () -> new MyAddressValidation()); + } + + @Override + public IAddressValidation newAddressValidationInstance(String className) { + return newInstance(className); + } + } + + @Test + public void testAddressVallidationFactory() { + //simulate osgi component service + BundleContext bc = TestActivator.context; + Dictionary properties = new Hashtable(); + properties.put("service.ranking", Integer.valueOf(1)); + ServiceRegistration sr = bc.registerService(IAddressValidationFactory.class, new MyAddressValidationFactory(), properties); + X_C_AddressValidationCfg cfg = new X_C_AddressValidationCfg(Env.getCtx(), 0, getTrxName()); + cfg.setAddressValidationClass(MyAddressValidation.class.getName()); + cfg.setHostAddress("localhost"); + cfg.setHostPort(8080); + cfg.setName("testAddressVallidation cfg"); + cfg.saveEx(); + MAddressValidation adv = new MAddressValidation(Env.getCtx(), 0, getTrxName()); + adv.setC_AddressValidationCfg_ID(cfg.get_ID()); + adv.setUserID("test"); + adv.setConnectionPassword("test01"); + adv.setSeqNo(10); + adv.setName("testAddressVallidation"); + var loader = Core.getAddressValidation(adv); + assertNotNull(loader); + assertTrue(loader instanceof MyAddressValidation); + sr.unregister(); + } + + private static final class MyTaxProvider extends StandardTaxProvider { + } + + private static final class MyTaxProviderFactory extends MappedByNameFactory implements ITaxProviderFactory { + public MyTaxProviderFactory() { + addMapping("MyTaxProvider", () -> new MyTaxProvider()); + } + + @Override + public ITaxProvider newTaxProviderInstance(String className) { + return newInstance(className); + } + } + + @Test + public void testTaxProviderFactory() { + //simulate osgi component service + BundleContext bc = TestActivator.context; + Dictionary properties = new Hashtable(); + properties.put("service.ranking", Integer.valueOf(1)); + ServiceRegistration sr = bc.registerService(ITaxProviderFactory.class, new MyTaxProviderFactory(), properties); + X_C_TaxProviderCfg cfg = new X_C_TaxProviderCfg(Env.getCtx(), 0, getTrxName()); + cfg.setName("testTaxProviderFactory cfg"); + cfg.setTaxProviderClass("MyTaxProvider"); + cfg.saveEx(); + MTaxProvider tp = new MTaxProvider(Env.getCtx(), 0, getTrxName()); + tp.setName("testTaxProviderFactory"); + tp.setC_TaxProviderCfg_ID(cfg.get_ID()); + tp.saveEx(); + var loader = Core.getTaxProvider(tp); + assertNotNull(loader); + assertTrue(loader instanceof MyTaxProvider); + sr.unregister(); + } + + private final static class MyReplenishInterface implements ReplenishInterface { + @Override + public BigDecimal getQtyToOrder(MWarehouse wh, X_T_Replenish replenish) { + return null; + } + } + + private final static class MyReplenishInterfaceFactory extends MappedByNameFactory implements IReplenishFactory { + public MyReplenishInterfaceFactory() { + addMapping(MyReplenishInterface.class.getName(), () -> new MyReplenishInterface()); + } + + @Override + public ReplenishInterface newReplenishInstance(String className) { + return newInstance(className); + } + } + + @Test + public void testReplenishFactory() { + //simulate osgi component service + BundleContext bc = TestActivator.context; + Dictionary properties = new Hashtable(); + properties.put("service.ranking", Integer.valueOf(1)); + bc.registerService(IReplenishFactory.class, new MyReplenishInterfaceFactory(), properties); + var loader = Core.getReplenish(MyReplenishInterface.class.getName()); + assertNotNull(loader); + assertTrue(loader instanceof MyReplenishInterface); + } + + private final static class MyPaymentExport extends GenericPaymentExport { + } + + private final static class MyPaymentExportFactory extends MappedByNameFactory implements IPaymentExporterFactory { + public MyPaymentExportFactory() { + addMapping(MyPaymentExport.class.getName(), () -> new MyPaymentExport()); + } + + @Override + public PaymentExport newPaymentExporterInstance(String className) { + return newInstance(className); + } + } + + @Test + public void testPaymentExporterFactory() { + //simulate osgi component service + BundleContext bc = TestActivator.context; + Dictionary properties = new Hashtable(); + properties.put("service.ranking", Integer.valueOf(1)); + bc.registerService(IPaymentExporterFactory.class, new MyPaymentExportFactory(), properties); + var loader = Core.getPaymentExporter(MyPaymentExport.class.getName()); + assertNotNull(loader); + assertTrue(loader instanceof MyPaymentExport); + } + + private final static class MyDepreciationMethod implements IDepreciationMethod { + @Override + public BigDecimal caclulateDepreciation(DepreciationDTO depreciationDTO) { + return null; + } + + @Override + public long getCountPeriod(DepreciationDTO depreciationDTO) { + return 0; + } + + @Override + public boolean isPeriodAdjustment() { + return false; + } + } + + private final static class MyDepreciationMethodFactory extends MappedByNameFactory implements IDepreciationMethodFactory { + public MyDepreciationMethodFactory() { + addMapping("MyDepreciationMethod", () -> new MyDepreciationMethod()); + } + + @Override + public IDepreciationMethod getDepreciationMethod(DepreciationFactoryLookupDTO factoryLookupDTO) { + return newInstance(factoryLookupDTO.depreciationType); + } + } + + @Test + public void testDepreciationMethodFactory() { + //simulate osgi component service + BundleContext bc = TestActivator.context; + Dictionary properties = new Hashtable(); + properties.put("service.ranking", Integer.valueOf(1)); + bc.registerService(IDepreciationMethodFactory.class, new MyDepreciationMethodFactory(), properties); + DepreciationFactoryLookupDTO dto = new DepreciationFactoryLookupDTO(); + dto.depreciationType = "MyDepreciationMethod"; + var loader = Core.getDepreciationMethod(dto); + assertNotNull(loader); + assertTrue(loader instanceof MyDepreciationMethod); + } +} diff --git a/org.idempiere.test/src/org/idempiere/test/model/MappedProcessFactoryTest.java b/org.idempiere.test/src/org/idempiere/test/base/MappedProcessFactoryTest.java similarity index 97% rename from org.idempiere.test/src/org/idempiere/test/model/MappedProcessFactoryTest.java rename to org.idempiere.test/src/org/idempiere/test/base/MappedProcessFactoryTest.java index cad2168c4f..a9f0f3be7a 100644 --- a/org.idempiere.test/src/org/idempiere/test/model/MappedProcessFactoryTest.java +++ b/org.idempiere.test/src/org/idempiere/test/base/MappedProcessFactoryTest.java @@ -22,7 +22,7 @@ * Contributors: * * - hengsin * **********************************************************************/ -package org.idempiere.test.model; +package org.idempiere.test.base; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -60,6 +60,7 @@ public class MappedProcessFactoryTest extends AbstractTestCase { @Test @Order(1) public void testDefaultMappedProcessFactory() { + //simulate call at plugin activator start method IMappedProcessFactory mappedFactory = Core.getMappedProcessFactory(); mappedFactory.addMapping(MyTest.class.getName(), () -> new MyTest()); @@ -71,6 +72,7 @@ public class MappedProcessFactoryTest extends AbstractTestCase { @Test @Order(2) public void testCustomMappedModelFactory() { + //simulate osgi component BundleContext bc = TestActivator.context; Dictionary properties = new Hashtable(); properties.put("service.ranking", Integer.valueOf(2));