一、在Ofbiz中新建一个SAP模块:Gradlew createPlugin -pPluginId=sap
二、在Sap模块的Lib文件夹中放个JCO文件。jco3.jar
三、在config文件夹下新增adap.properties文件,放入SAP的连接配置信息:,内容如下:
jco.client.ashost=192.168.1.12
jco.client.sysnr=00
jco.client.client=800
jco.client.user=rfcuser
jco.client.passwd=rfcuserpwd
jco.client.lang=zh
四、为了使SAP的连接函数知道从哪里读取配置信息,需要实用DestinationDataProvider接口,代码如下:
package org.apache.ofbiz.plugins.sap;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import org.apache.ofbiz.base.util.UtilProperties;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoDestinationManager;
import com.sap.conn.jco.JCoException;
import com.sap.conn.jco.ext.DestinationDataEventListener;
import com.sap.conn.jco.ext.DestinationDataProvider;
import com.sap.conn.jco.ext.Environment;
public class FileDestinationDataProviderImp implements DestinationDataProvider {
@Override
public Properties getDestinationProperties(String destName)
{
return UtilProperties.getProperties(destName);
}
@Override
public void setDestinationDataEventListener(DestinationDataEventListener listener)
{
throw new UnsupportedOperationException();
}
@Override
public boolean supportsEvents()
{
return false;
}
public static JCoDestination getDestination(String fileName) throws JCoException
{
FileDestinationDataProviderImp destDataProvider = new FileDestinationDataProviderImp();
try {
Environment.registerDestinationDataProvider(destDataProvider);
} catch (Exception e) {
// TODO: handle exception
}
JCoDestination dest = JCoDestinationManager.getDestination(fileName);
return dest;
}
}
五、配置调用SAP函数的实现类的服务,在service.xml中新加一个服务定义。参数functionName表示RFC函数的名称。
<service name="runSapFunction" engine="java" location="org.apache.ofbiz.plugins.sap.SapWorker" invoke="runSapFunction">
<attribute name="functionName" mode="IN" type="String"></attribute>
<attribute name="functionParameters" mode="IN" type="Map" optional="true"></attribute>
<attribute name="result" mode="OUT" type="Map"></attribute>
</service>
六‘、SapWorker类的实现代码:
package org.apache.ofbiz.plugins.sap;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.ofbiz.service.DispatchContext;
import com.sap.conn.jco.AbapException;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoField;
import com.sap.conn.jco.JCoFunction;
import com.sap.conn.jco.JCoParameterList;
import com.sap.conn.jco.JCoRecordField;
import com.sap.conn.jco.JCoRecordFieldIterator;
import com.sap.conn.jco.JCoStructure;
import com.sap.conn.jco.JCoTable;
public class SapWorker {
/**执行SAP函数并返回
* @param ctx
* @param context
* @return
*/
public static Map<String, Object> runSapFunction(DispatchContext ctx, Map<String, ? extends Object> context){
Map<String, Object> result = new HashMap<>();
Map<String, Object> map = new HashMap<>();
String functionName=(String) context.get("functionName");
Map functionParameters=(Map)context.get("functionParameters");
try {
JCoDestination destination = FileDestinationDataProviderImp.getDestination("abap.properties");
//Get metadata of function module "STFC_CONNECTION"
JCoFunction function = destination.getRepository().getFunction(functionName);
if (function == null)
throw new RuntimeException("TFC_CONNECTION not found in SAP.");
//Call Function
if(functionParameters!=null){
if(functionParameters.containsKey("IMPORT")){
Map<String,Object> importMap=(Map<String,Object>)functionParameters.get("IMPORT");
JCoParameterList jcoParameterList=function.getImportParameterList();
for(Map.Entry<String,Object> importParameter: importMap.entrySet()){
setValueToJCoParameterList(jcoParameterList,importParameter.getKey(),importParameter.getValue());
}
}
if(functionParameters.containsKey("CHANGE")){
Map<String,Object> importMap=(Map<String,Object>)functionParameters.get("CHANGE");
JCoParameterList jcoParameterList=function.getChangingParameterList();
for(Map.Entry<String,Object> importParameter: importMap.entrySet()){
setValueToJCoParameterList(jcoParameterList,importParameter.getKey(),importParameter.getValue());
}
}
if(functionParameters.containsKey("TABLES")){
Map<String,List> importMap=(Map<String,List>)functionParameters.get("TABLES");
JCoParameterList jcoParameterList=function.getTableParameterList();
for(Map.Entry<String,List> importParameter: importMap.entrySet()){
setValueToJCoTable(jcoParameterList,importParameter.getKey(),importParameter.getValue());
}
}
}
function.execute(destination);
JCoParameterList jcoExportParameterList=function.getExportParameterList();
if(jcoExportParameterList!=null){
Map<String,Object> exportMap=new HashMap<String,Object>();
for(JCoField jcoParameter :jcoExportParameterList){
exportMap.put(jcoParameter.getName(),convertJCoParameterListToMap(jcoParameter));
}
map.put("EXPORT",exportMap);
}
JCoParameterList jcoChangeParameterList=function.getChangingParameterList();
if(jcoChangeParameterList!=null){
Map<String,Object> imortMap=new HashMap<String,Object>();
for(JCoField jcoParameter :jcoChangeParameterList){
imortMap.put(jcoParameter.getName(),convertJCoParameterListToMap(jcoParameter));
}
map.put("CHANGE",imortMap);
}
JCoParameterList jcoTableParameterList=function.getTableParameterList();
if(jcoTableParameterList!=null){
Map<String,Object> table=new HashMap<String,Object>();
for(JCoField jcoTable :jcoTableParameterList){
table.put(jcoTable.getName(),convertJCoTableToList(jcoTable));
}
map.put("TABLES",table);
}
} catch (Exception e) {
System.out.println(e.toString());
}
result.put("result",map);
return result;
}
/** 将Map的函数写入SAP函数表中
* @param jcoParameterList
* @param tableName
* @param tableRows
*/
static void setValueToJCoTable(JCoParameterList jcoParameterList,String tableName,List tableRows){
JCoTable jcoTable=jcoParameterList.getTable(tableName);
for(Object tableRow :tableRows){
Map<String,Object> tableRowMap=(Map<String,Object>)tableRow;
jcoTable.appendRow();
for(Map.Entry<String,Object> importParameter: tableRowMap.entrySet()){
jcoTable.setValue(importParameter.getKey(),importParameter.getValue());
}
}
}
/**将Map的函数写入SAP函数表中
* @param jcoParameterList
* @param parameterName
* @param parameterValue
*/
static void setValueToJCoParameterList(JCoParameterList jcoParameterList,String parameterName,Object parameterValue){
if(parameterValue instanceof Map){
Map parameterValueMap=(Map)parameterValue;
JCoStructure jcoStruce=jcoParameterList.getStructure(parameterName);
JCoRecordFieldIterator recordFieldIterator=jcoStruce.getRecordFieldIterator();
JCoRecordField recordField=recordFieldIterator.nextRecordField();
while(recordField!=null){
String recordFieldName=recordField.getName();
if(parameterValueMap.containsKey(recordFieldName)){
recordField.setValue(parameterValueMap.get("recordFieldName"));
}
recordField=recordFieldIterator.nextRecordField();
}
}else{
jcoParameterList.setValue(parameterName,parameterValue);
}
}
static Map convertJCoParameterListToMap(JCoField jcoParameter){
LinkedHashMap m = new LinkedHashMap();
m.put("fieldtype",jcoParameter.getType());
return m;
}
static List<Map<String,Object>> convertJCoTableToList(JCoField table)
{
LinkedList l = new LinkedList();
JCoTable t = table.getTable();
for (int i = 0; i < t.getNumRows(); i++)
{
t.setRow(i);
LinkedHashMap m = new LinkedHashMap();
for(JCoField f: t){
m.put(f.getName(), t.getValue(f.getName()));
}
l.add(m);
}
return l;
}
}
六、下面是一个调用 SAP函数的示例:
dispatcher.runSync("runSapFunction",UtilMisc.toMap("functionName","RFC_MES_SAPDATA","functionParameters",UtilMisc.toMap("IMPORT",UtilMisc.toMap("SAUFNR","001100011210"))))