Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member

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 --------------

Labels in this area