IDEMPIERE-4695 Add document factory base class backed by Map and Lambda functional object (#572)
This commit is contained in:
parent
3a1d53ea4e
commit
c159ce5325
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="org.adempiere.base.MappedDocumentFactory">
|
||||||
|
<property name="service.ranking" type="Integer" value="1"/>
|
||||||
|
<property name="gaap" value="*"/>
|
||||||
|
<service>
|
||||||
|
<provide interface="org.adempiere.base.IDocFactory"/>
|
||||||
|
<provide interface="org.adempiere.base.IMappedDocumentFactory"/>
|
||||||
|
</service>
|
||||||
|
<implementation class="org.adempiere.base.MappedDocumentFactory"/>
|
||||||
|
</scr:component>
|
|
@ -1002,4 +1002,26 @@ public class Core {
|
||||||
}
|
}
|
||||||
return factoryService;
|
return factoryService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static IServiceReferenceHolder<IMappedDocumentFactory> s_mappedDocumentFactoryReference = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return {@link IMappedDocumentFactory}
|
||||||
|
*/
|
||||||
|
public static IMappedDocumentFactory getMappedDocumentFactory() {
|
||||||
|
IMappedDocumentFactory factoryService = null;
|
||||||
|
if (s_mappedDocumentFactoryReference != null) {
|
||||||
|
factoryService = s_mappedDocumentFactoryReference.getService();
|
||||||
|
if (factoryService != null)
|
||||||
|
return factoryService;
|
||||||
|
}
|
||||||
|
|
||||||
|
IServiceReferenceHolder<IMappedDocumentFactory> serviceReference = Service.locator().locate(IMappedDocumentFactory.class).getServiceReference();
|
||||||
|
if (serviceReference != null) {
|
||||||
|
factoryService = serviceReference.getService();
|
||||||
|
s_mappedDocumentFactoryReference = serviceReference;
|
||||||
|
}
|
||||||
|
return factoryService;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
package org.adempiere.base;
|
package org.adempiere.base;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
@ -23,7 +22,6 @@ import org.compiere.model.MAcctSchema;
|
||||||
import org.compiere.model.MTable;
|
import org.compiere.model.MTable;
|
||||||
import org.compiere.util.AdempiereUserError;
|
import org.compiere.util.AdempiereUserError;
|
||||||
import org.compiere.util.CLogger;
|
import org.compiere.util.CLogger;
|
||||||
import org.compiere.util.DB;
|
|
||||||
import org.compiere.util.Env;
|
import org.compiere.util.Env;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,42 +33,6 @@ public class DefaultDocumentFactory implements IDocFactory {
|
||||||
|
|
||||||
private final static CLogger s_log = CLogger.getCLogger(DefaultDocumentFactory.class);
|
private final static CLogger s_log = CLogger.getCLogger(DefaultDocumentFactory.class);
|
||||||
|
|
||||||
@Override
|
|
||||||
public Doc getDocument(MAcctSchema as, int AD_Table_ID, int Record_ID,
|
|
||||||
String trxName) {
|
|
||||||
String tableName = MTable.getTableName(Env.getCtx(), AD_Table_ID);
|
|
||||||
//
|
|
||||||
Doc doc = null;
|
|
||||||
StringBuilder sql = new StringBuilder("SELECT * FROM ")
|
|
||||||
.append(tableName)
|
|
||||||
.append(" WHERE ").append(tableName).append("_ID=? AND Processed='Y'");
|
|
||||||
PreparedStatement pstmt = null;
|
|
||||||
ResultSet rs = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
pstmt = DB.prepareStatement (sql.toString(), trxName);
|
|
||||||
pstmt.setInt (1, Record_ID);
|
|
||||||
rs = pstmt.executeQuery ();
|
|
||||||
if (rs.next ())
|
|
||||||
{
|
|
||||||
doc = getDocument(as, AD_Table_ID, rs, trxName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
s_log.severe("Not Found: " + tableName + "_ID=" + Record_ID);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
s_log.log (Level.SEVERE, sql.toString(), e);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
DB.close(rs, pstmt);
|
|
||||||
rs = null;
|
|
||||||
pstmt = null;
|
|
||||||
}
|
|
||||||
return doc;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Doc getDocument(MAcctSchema as, int AD_Table_ID, ResultSet rs,
|
public Doc getDocument(MAcctSchema as, int AD_Table_ID, ResultSet rs,
|
||||||
String trxName) {
|
String trxName) {
|
||||||
|
|
|
@ -13,10 +13,16 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
package org.adempiere.base;
|
package org.adempiere.base;
|
||||||
|
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import org.compiere.acct.Doc;
|
import org.compiere.acct.Doc;
|
||||||
import org.compiere.model.MAcctSchema;
|
import org.compiere.model.MAcctSchema;
|
||||||
|
import org.compiere.model.MTable;
|
||||||
|
import org.compiere.util.CLogger;
|
||||||
|
import org.compiere.util.DB;
|
||||||
|
import org.compiere.util.Env;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -24,6 +30,7 @@ import org.compiere.model.MAcctSchema;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public interface IDocFactory {
|
public interface IDocFactory {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create Posting document
|
* Create Posting document
|
||||||
* @param as accounting schema
|
* @param as accounting schema
|
||||||
|
@ -32,7 +39,27 @@ public interface IDocFactory {
|
||||||
* @param trxName transaction name
|
* @param trxName transaction name
|
||||||
* @return Document or null
|
* @return Document or null
|
||||||
*/
|
*/
|
||||||
public Doc getDocument(MAcctSchema as, int AD_Table_ID, int Record_ID, String trxName);
|
public default Doc getDocument(MAcctSchema as, int AD_Table_ID, int Record_ID, String trxName) {
|
||||||
|
String tableName = MTable.getTableName(Env.getCtx(), AD_Table_ID);
|
||||||
|
//
|
||||||
|
Doc doc = null;
|
||||||
|
StringBuilder sql = new StringBuilder("SELECT * FROM ")
|
||||||
|
.append(tableName)
|
||||||
|
.append(" WHERE ")
|
||||||
|
.append(tableName).append("_ID=? AND Processed='Y'");
|
||||||
|
try (PreparedStatement pstmt = DB.prepareStatement (sql.toString(), trxName);) {
|
||||||
|
pstmt.setInt (1, Record_ID);
|
||||||
|
ResultSet rs = pstmt.executeQuery ();
|
||||||
|
if (rs.next ()) {
|
||||||
|
doc = getDocument(as, AD_Table_ID, rs, trxName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CLogger.getCLogger(getClass()).severe("Not Found: " + tableName + "_ID=" + Record_ID);
|
||||||
|
} catch (Exception e) {
|
||||||
|
CLogger.getCLogger(getClass()).log (Level.SEVERE, sql.toString(), e);
|
||||||
|
}
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create Posting document
|
* Create Posting document
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
/***********************************************************************
|
||||||
|
* 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.sql.ResultSet;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.compiere.acct.Doc;
|
||||||
|
import org.compiere.model.MAcctSchema;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author hengsin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface IMappedDocumentFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add table name + gaap (optional) to Doc mapping
|
||||||
|
* @param gaap map to c_acctschema.gaap (optional)
|
||||||
|
* @param tableName
|
||||||
|
* @param supplier
|
||||||
|
*/
|
||||||
|
public void addMapping(String gaap, String tableName, Function<Parameter, ? extends Doc> supplier);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param gaap
|
||||||
|
* @param tableName
|
||||||
|
*/
|
||||||
|
public void removeMapping(String gaap, String tableName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* parameter class for doc supplier
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public final static class Parameter {
|
||||||
|
public MAcctSchema as;
|
||||||
|
public ResultSet rs;
|
||||||
|
public String trxName;
|
||||||
|
|
||||||
|
public Parameter(MAcctSchema as, ResultSet rs, String trxName) {
|
||||||
|
this.as = as;
|
||||||
|
this.rs = rs;
|
||||||
|
this.trxName = trxName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
/***********************************************************************
|
||||||
|
* 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.sql.ResultSet;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.compiere.acct.Doc;
|
||||||
|
import org.compiere.model.MAcctSchema;
|
||||||
|
import org.compiere.model.MTable;
|
||||||
|
import org.compiere.util.Env;
|
||||||
|
import org.compiere.util.Util;
|
||||||
|
import org.osgi.service.component.annotations.Component;
|
||||||
|
|
||||||
|
@Component(name = "org.adempiere.base.MappedDocumentFactory",
|
||||||
|
service = {IDocFactory.class, IMappedDocumentFactory.class},
|
||||||
|
immediate = true,
|
||||||
|
property = {"service.ranking:Integer=1", "gaap=*"})
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Document factory backed by map between tablename + gaap and lambda function object.
|
||||||
|
* If you create a subclass of this and register it as osgi service, don't register for the IMappedDocumentFactory interface.
|
||||||
|
* @author hengsin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class MappedDocumentFactory implements IDocFactory, IMappedDocumentFactory {
|
||||||
|
|
||||||
|
private final ConcurrentHashMap<String, Function<Parameter, ? extends Doc>> documentMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* default constructor
|
||||||
|
*/
|
||||||
|
public MappedDocumentFactory() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Doc getDocument(MAcctSchema as, int AD_Table_ID, ResultSet rs, String trxName) {
|
||||||
|
String tableName = MTable.getTableName(Env.getCtx(), AD_Table_ID);
|
||||||
|
String key = tableName + "|" + as.getGAAP();
|
||||||
|
Function<Parameter, ? extends Doc> function = documentMap.get(key);
|
||||||
|
if (function != null) {
|
||||||
|
return function.apply(new Parameter(as, rs, trxName));
|
||||||
|
}
|
||||||
|
|
||||||
|
key = tableName + "|*";
|
||||||
|
function = documentMap.get(key);
|
||||||
|
if (function != null) {
|
||||||
|
return function.apply(new Parameter(as, rs, trxName));
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addMapping(String gaap, String tableName, Function<Parameter, ? extends Doc> supplier) {
|
||||||
|
StringBuilder key = new StringBuilder();
|
||||||
|
key.append(tableName).append("|");
|
||||||
|
if (Util.isEmpty(gaap, true))
|
||||||
|
key.append("*");
|
||||||
|
else
|
||||||
|
key.append(gaap);
|
||||||
|
documentMap.put(key.toString(), supplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeMapping(String gaap, String tableName) {
|
||||||
|
StringBuilder key = new StringBuilder();
|
||||||
|
key.append(tableName).append("|");
|
||||||
|
if (Util.isEmpty(gaap, true))
|
||||||
|
key.append("*");
|
||||||
|
else
|
||||||
|
key.append(gaap);
|
||||||
|
documentMap.remove(key.toString());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
/***********************************************************************
|
||||||
|
* 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 org.adempiere.base.Core;
|
||||||
|
import org.adempiere.base.IMappedDocumentFactory;
|
||||||
|
import org.compiere.acct.Doc;
|
||||||
|
import org.compiere.acct.DocManager;
|
||||||
|
import org.compiere.acct.Doc_InOut;
|
||||||
|
import org.compiere.model.MAcctSchema;
|
||||||
|
import org.compiere.model.MClientInfo;
|
||||||
|
import org.compiere.model.MInOut;
|
||||||
|
import org.compiere.util.Env;
|
||||||
|
import org.idempiere.test.AbstractTestCase;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author hengsin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class MappedDocumentFactoryTest extends AbstractTestCase {
|
||||||
|
|
||||||
|
public MappedDocumentFactoryTest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefaultMappedDocumentFactory() {
|
||||||
|
IMappedDocumentFactory factory = Core.getMappedDocumentFactory();
|
||||||
|
factory.addMapping(null, MInOut.Table_Name, (p) -> new MyDocInOut(p.as, p.rs, p.trxName));
|
||||||
|
|
||||||
|
int C_AcctSchema_ID = MClientInfo.get().getC_AcctSchema1_ID();
|
||||||
|
MAcctSchema as = new MAcctSchema(Env.getCtx(), C_AcctSchema_ID, getTrxName());
|
||||||
|
Doc doc = DocManager.getDocument(as, MInOut.Table_ID, 100, getTrxName());
|
||||||
|
assertTrue(doc != null && doc instanceof MyDocInOut, "Doc not instanceof MyDocInOut. " + (doc == null ? "Doc is Null" : "Doc="+doc.getClass().getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private final static class MyDocInOut extends Doc_InOut {
|
||||||
|
|
||||||
|
public MyDocInOut(MAcctSchema as, ResultSet rs, String trxName) {
|
||||||
|
super(as, rs, trxName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue