So I downloaded the Java connector sapjco3.jar and the examples and started to play.
I soon got put off by the fact that all the examples require a username and password to be stored in a file and the idoc example I found was a bit over complicated for someone coming from an ABAP background.
Much Googling later and here is what I ended up with. This stores the system connection details in a file but NOT the username and password.
The idoc is created by calling a RFC function and the bit that casts a JCoStructure into a String (to populate the sdata field) is quite useful (I think).
--------- Start Java Code --------------
import java.util.HashMap;
import java.util.Properties;
import java.io.FileInputStream;
import java.io.IOException;
import com.sap.conn.jco.*;
import com.sap.conn.jco.rt.*;
import com.sap.conn.jco.ext.*;
/**
* This is the example that SAP should have delivered It keeps the system name
* etc in a file but not the user and password
*
* It will call a RFC function to create an idoc and print out the returned data
*
* Create a file called ABAP_AS.jcoDestination as below
* jco.client.lang=<language>
* jco.client.client=<client>
* jco.client.sysnr=<system number>
* jco.client.ashost=<hostname>
*
* Enter the required values starting lines: 158,185,196
* Install sapjco3,
* set environment variables: classpath, lib_path and path
* Compile with : javac iDocTest.java
* Run with command java iDocTest
*/
public class iDocTest {
static String ABAP_AS = "ABAP_AS";
static class MyDestinationDataProvider implements DestinationDataProvider {
private DestinationDataEventListener eL;
private HashMap<String, Properties> secureDBStorage = new HashMap<String, Properties>();
public Properties getDestinationProperties(String destinationName) {
try {
//read the destination from DB
Properties p = secureDBStorage.get(destinationName);
if (p != null) {
//check if all is correct, for example
if (p.isEmpty()) {
throw new DataProviderException(DataProviderException.Reason.INVALID_CONFIGURATION, "destination configuration is incorrect", null);
}
return p;
}
return null;
} catch (RuntimeException re) {
throw new DataProviderException(DataProviderException.Reason.INTERNAL_ERROR, re);
}
}
//An implementation supporting events has to retain the eventListener instance provided
//by the JCo runtime. This listener instance shall be used to notify the JCo runtime
//about all changes in destination configurations.
public void setDestinationDataEventListener(DestinationDataEventListener eventListener) {
this.eL = eventListener;
}
public boolean supportsEvents() {
return true;
}
//implementation that saves the properties in a very secure way
void changeProperties(String destName, Properties properties) {
synchronized (secureDBStorage) {
if (properties == null) {
if (secureDBStorage.remove(destName) != null) {
eL.deleted(destName);
}
} else {
secureDBStorage.put(destName, properties);
eL.updated(destName); // create or updated
}
}
}
} // end of MyDestinationDataProvider
static Properties getDestinationPropertiesFromUI() {
Properties userProperties;
Properties sapProperties;
String JCO_CLIENT;
String JCO_LANG;
String JCO_SYSNR;
String JCO_HOST;
sapProperties = new Properties();
userProperties = new Properties();
// Load ABAP_AS.jcoDestination file
try {
sapProperties.load(new FileInputStream("ABAP_AS.jcoDestination"));
} catch (IOException ex) {
ex.printStackTrace();
}
// Get fixed connection details from properties file
JCO_LANG = sapProperties.getProperty("jco.client.lang");
JCO_HOST = sapProperties.getProperty("jco.client.ashost");
JCO_SYSNR = sapProperties.getProperty("jco.client.sysnr");
JCO_CLIENT = sapProperties.getProperty("jco.client.client");
// Set connection details from strings retrieved fromn file above
userProperties.setProperty(DestinationDataProvider.JCO_ASHOST, JCO_HOST);
userProperties.setProperty(DestinationDataProvider.JCO_SYSNR, JCO_SYSNR);
userProperties.setProperty(DestinationDataProvider.JCO_CLIENT, JCO_CLIENT);
userProperties.setProperty(DestinationDataProvider.JCO_LANG, JCO_LANG);
// Get username and password
System.console().printf("Enter user:");
userProperties.setProperty(DestinationDataProvider.JCO_USER, System.console().readLine());
System.console().printf("Enter password:");
userProperties.setProperty(DestinationDataProvider.JCO_PASSWD, System.console().readLine());
return userProperties;
}
public static void iDocCall(String destName) throws JCoException {
//Declare destination for function call
JCoDestination destination = JCoDestinationManager.getDestination(destName);
String client = destination.getClient();
// Declare function and check it exists
JCoFunction idoc_input = destination.getRepository().getFunction("IDOC_INBOUND_SINGLE");
if (idoc_input == null) {
throw new RuntimeException("IDOC_INBOUND_SINGLE not found in SAP.");
}
// Declare function fields, structures and tables
//JCoFunction is container for function values. Each function contains separate
//containers for import, export, changing and table parameters.
//To set or get the parameters use the APIS setValue() and getXXX().
// Declare:
// Import Fields
// idoc_input.getImportParameterList().setValue("MASS_PROCESSING", " ");
// Structures
JCoStructure idoc_control = idoc_input.getImportParameterList().getStructure("PI_IDOC_CONTROL_REC_40");
//Tables
JCoTable idoc_data = idoc_input.getTableParameterList().getTable("PT_IDOC_DATA_RECORDS_40");
// Populate function fields, structures and tables
// To create the idoc we only need to set the control and data
//iDoc Control
idoc_control.setValue("MANDT", client);
idoc_control.setValue("DIRECT", "2");
idoc_control.setValue("MESTYP", "MBGMCR");
idoc_control.setValue("IDOCTYP", "MBGMCR02");
idoc_control.setValue("CIMTYP", "ZMBGMCR02001");
idoc_control.setValue("SNDPOR", <enter_sndpor>);
idoc_control.setValue("SNDPRT", <enter_sndprt>);
idoc_control.setValue("SNDPRN", <enter_sndprn>);
idoc_control.setValue("RCVPOR", <enter_rcvpor>);
idoc_control.setValue("RCVPRT", <enter_rcvprt>);
idoc_control.setValue("RCVPRN", <enter_rcvprn>);
//iDoc Data
JCoRepository repository = destination.getRepository();
JCoStructure str_head, str_item;
JCoRecordMetaData meta_head, meta_item;
String sdata = "";
//Create structures for sdata population
meta_head = repository.getStructureDefinition("E1BP2017_GM_HEAD_01");
str_head = JCo.createStructure(meta_head);
meta_item = repository.getStructureDefinition("E1BP2017_GM_ITEM_CREATE");
str_item = JCo.createStructure(meta_item);
// Write idoc data
idoc_data.appendRows(2); // Add 4 rows to internal table
idoc_data.setValue("MANDT", client);
idoc_data.setValue("SEGNUM", "1");
idoc_data.setValue("PSGNUM", "0");
idoc_data.setValue("SEGNAM", "E1BP2017_GM_HEAD_01");
str_head.setValue("HEADER_TXT", "Java test");
str_head.setValue("PSTNG_DATE", "20131008");
str_head.setValue("REF_DOC_NO", "12345");
sdata = ConvertToSDATA(str_head, meta_head);
idoc_data.setValue("SDATA", sdata);
idoc_data.nextRow(); // Move to next row
idoc_data.setValue("MANDT", client);
idoc_data.setValue("SEGNUM", "2");
idoc_data.setValue("PSGNUM", "0");
idoc_data.setValue("SEGNAM", "E1BP2017_GM_ITEM_CREATE");
str_item.setValue("MATERIAL", <enter_material>);
str_item.setValue("BATCH", <enter_batch>);
str_item.setValue("ENTRY_QNT", <enter_qty>);
str_item.setValue("EXPIRYDATE", <enter_sled_date>);
sdata = ConvertToSDATA(str_item, meta_item);
idoc_data.setValue("SDATA", sdata);
//To set or get the parameters use the APIS setValue() and getValue().
idoc_input.getTableParameterList().setValue("PT_IDOC_DATA_RECORDS_40", idoc_data);
// Execute the function call
try {
idoc_input.execute(destination);
} catch (AbapException e) {
System.out.println(e.toString());
return;
}
// Get returned idoc number
String idoc_number;
idoc_number = idoc_input.getExportParameterList().getString("PE_IDOC_NUMBER");
// Remove leading zeros from idoc number
idoc_number = idoc_number.replaceFirst("^0*", "");
if (idoc_number.isEmpty()) {
idoc_number = "0";
}
// Write out idoc number
System.out.println("Created idoc number " + idoc_number);
}
public static String ConvertToSDATA(JCoStructure data_in, JCoRecordMetaData meta_in) {
/*
Simply casting the structure to a string will fail (won't compile)
Concatenating the structure fields into a string will remove all the spaces
so the field alignment is lost.
The solution is to create a StringBuilder object of the correct length
Initialize it with all spaces and then, using the structure metadata,
insert each field at the correct start position
* NB: This works for idocs where all fields are character types
*/
String sdata = "";
int count = 0;
int Start = 0;
int End = 0;
int Len = 0;
// Declare string builder as 1000 long and fill with spaces
StringBuilder strB = new StringBuilder(" ");
strB.setLength(1000);
ClearString1000(strB, 1000);
// Get field count in structure
count = meta_in.getFieldCount();
count = count - 1;
for (int i = 0; i <= count; i++) {
Len = meta_in.getLength(i);
End = Start + Len;
strB.insert(Start, data_in.getValue(i));
Start = End++;
}
sdata = strB.toString();
return sdata;
}
public static StringBuilder ClearString1000(StringBuilder str, int Len) {
// Sets all characters to space
for (int i = 1; i <= Len; i++) {
str.insert(i, " ");
}
return str;
}
public static void main(String[] args) throws JCoException {
MyDestinationDataProvider myProvider = new MyDestinationDataProvider();
//register the provider with the JCo environment;
//catch IllegalStateException if an instance is already registered
try {
com.sap.conn.jco.ext.Environment.registerDestinationDataProvider(myProvider);
} catch (IllegalStateException providerAlreadyRegisteredException) {
//somebody else registered its implementation,
//stop the execution
throw new Error(providerAlreadyRegisteredException);
}
String destName = "ABAP_AS";
iDocTest dest;
dest = new iDocTest();
//set properties for the destination and ...
myProvider.changeProperties(destName, getDestinationPropertiesFromUI());
//... work with it
iDocTest.iDocCall(destName);
//Clear the properties and ...
myProvider.changeProperties(destName, null);
}
}
--------- End Java Code --------------
User | Count |
---|---|
11 | |
10 | |
5 | |
5 | |
4 | |
4 | |
4 | |
3 | |
3 | |
3 |