UPDATE! The community will be go into read-only on April 19, 8am Pacific in preparation for migration on April 21. Read more.
UPDATE! The community will be go into read-only on April 19, 8am Pacific in preparation for migration on April 21.Read more.
Absent Member.
Absent Member.
1658 views

How to use DataTypeArray (or CustomRecordArray)

Jump to solution

[Migrated content. Thread originally posted on 05 March 2012]

Hi

I am already using DataType to synchronize between Java and Cobol using a CobolBean (procedural Cobol) on UNIX Server Express.
Now I need a mechanism to use arrays (occurs). I can imagine that jarray will work.
How can I use DataTypeArray (or the similar CustomRecordArray). Does somebody have an example.
Maybe moving to use OOCobol in some parts.

Thanks in advance
Simon

0 Likes
1 Solution

Accepted Solutions
Micro Focus Expert
Micro Focus Expert
cobcall will then traverse the requestArray for the Objects, calling getBytes() and concatenating the results. Moving the result into "01 request" specified by the using clause.
Is that correct ?


Yes, that is correct, the same is true for a CustomRecord but it invokes getParameters/setParameters instead.

The DataType/DataTypeArray mechanism gives you ultimate control over the memory represenation being passed to
COBOL; where as the CustomRecord approach treats each object as a specific field size. I've include a sample below using your scenerio above.

Is there a way for Cobol to find out the number of elements sent or should I use a separate dataitem providing the count in the using clause ?

Unfortunetly not and if you address an element outside of the range passed in the Runtime will give you a RTS114, so I would pass count so you can restrict the access to elements you have passed in.



      $set remove(detail)
       local-storage section.
       01 counter      binary-long.
       linkage section.
       01 request.
          05 detail occurs 10 times.
               10 field1 pic x(20).
               10 field2 pic 9(10).

       procedure division using request.
           perform varying counter from 1 by 1 until counter equals 10
              display counter " ->" field1 of detail(counter) " == "
                  field2 of detail(counter)
           end-perform



import com.microfocus.cobol.CobolException;
import com.microfocus.cobol.RuntimeSystem;
import com.microfocus.cobol.lang.CustomRecordArray;
import com.microfocus.cobol.lang.ParameterList;


public class TestDetailsArray
{
    public static void main(String[] args) throws CobolException, Exception
    {
        Detail details[] = new Detail[10];
        for(int c=0; c<details.length; c++)
        {
            details[c]= new Detail("Field_"+c, String.valueOf(c*100));
        }
        
        RuntimeSystem.cobcall("cobprog", new ParameterList().add(new CustomRecordArray(details)));
    }
}



import com.microfocus.cobol.lang.CustomRecord;
import com.microfocus.cobol.lang.ParameterList;


public class Detail implements CustomRecord
{
    private String field1;
    private String field2;
    
    public Detail(String field1, String field2)
    {
        this.field1 = stringFixSize(field1, 20);
        this.field2 = numberFixSize(field2, 10);
    }
    
    private String numberFixSize(String inField, int length)
    {
        /* too big or exact size.. */
        if (inField.length() >= length)
        {
            return inField.substring(0, length);
        }
        
        StringBuilder sb = new StringBuilder();
        for(int c=0; c<length-inField.length(); c++)
        {
            sb.append('0');
        }
        
        sb.append(inField);
        return sb.toString();
    }

    private String stringFixSize(String inField, int length)
    {
        /* too big or exact size.. */
        if (inField.length() >= length)
        {
            return inField.substring(0, length);
        }
        
        StringBuilder sb = new StringBuilder();
        
        sb.append(inField);
        for(int c=0; c<length-inField.length(); c++)
        {
            sb.append(' ');
        }
        return sb.toString();
    }

    @Override
    public Object[] getParameters()
    {
        return new ParameterList().add(field1).add(field2).getArguments();
    }

    @Override
    public void setParameters(Object[] parms)
    {
        this.field1 = (String)parms[0];
        this.field2 = (String)parms[1];
    }

}




g:\java.playground>java -cp "bin;.;%CLASSPATH%" TestDetailsArray
+0000000001 ->Field_0              == 0000000000
+0000000002 ->Field_1              == 0000000100
+0000000003 ->Field_2              == 0000000200
+0000000004 ->Field_3              == 0000000300
+0000000005 ->Field_4              == 0000000400
+0000000006 ->Field_5              == 0000000500
+0000000007 ->Field_6              == 0000000600
+0000000008 ->Field_7              == 0000000700
+0000000009 ->Field_8              == 0000000800

View solution in original post

0 Likes
4 Replies
Micro Focus Expert
Micro Focus Expert
The use of DataTypeArray and CustomRecordArray will depend on what type of Objects you want in the array...

For example if the objects already use the Datatype mechanism then then DatatypeArray is it container, simularly
for CustomRecord/CustomRecordArray.

If you have a specific example then we can talk specifics.
0 Likes
Absent Member.
Absent Member.
I have a class extending CobolBean with the following call:
super.cobcall("cobprog", new ParameterList().add(request).add(response));

where request and response are: public class MyRequestMsg implements DataType
and implement getBytes() and synchronizeData(). Which use/return a byte[] for the private variables for the Cobol record fields.

As far as I understood you, I can do the following

requestArray = new DataTyeArray()
requestArray .add(new(MyRequestDetailMsg(......))
requestArray .add(new(MyRequestDetailMsg(......))
requestArray .add(new(MyRequestDetailMsg(......))
super.cobcall("cobprog", new ParameterList().add(requestArray).add(response));

were MyRequestDetailMsg is the "05 detail".

01 request
05 detail occurs 10 times
10 field1 pic x(20)
10 field2 pic 9(10)

cobcall will then traverse the requestArray for the Objects, calling getBytes() and concatenating the results. Moving the result into "01 request" specified by the using clause.
Is that correct ?

Is there a way for Cobol to find out the number of elements sent or should I use a separate dataitem providing the count in the using clause ?

Simon
0 Likes
Micro Focus Expert
Micro Focus Expert
cobcall will then traverse the requestArray for the Objects, calling getBytes() and concatenating the results. Moving the result into "01 request" specified by the using clause.
Is that correct ?


Yes, that is correct, the same is true for a CustomRecord but it invokes getParameters/setParameters instead.

The DataType/DataTypeArray mechanism gives you ultimate control over the memory represenation being passed to
COBOL; where as the CustomRecord approach treats each object as a specific field size. I've include a sample below using your scenerio above.

Is there a way for Cobol to find out the number of elements sent or should I use a separate dataitem providing the count in the using clause ?

Unfortunetly not and if you address an element outside of the range passed in the Runtime will give you a RTS114, so I would pass count so you can restrict the access to elements you have passed in.



      $set remove(detail)
       local-storage section.
       01 counter      binary-long.
       linkage section.
       01 request.
          05 detail occurs 10 times.
               10 field1 pic x(20).
               10 field2 pic 9(10).

       procedure division using request.
           perform varying counter from 1 by 1 until counter equals 10
              display counter " ->" field1 of detail(counter) " == "
                  field2 of detail(counter)
           end-perform



import com.microfocus.cobol.CobolException;
import com.microfocus.cobol.RuntimeSystem;
import com.microfocus.cobol.lang.CustomRecordArray;
import com.microfocus.cobol.lang.ParameterList;


public class TestDetailsArray
{
    public static void main(String[] args) throws CobolException, Exception
    {
        Detail details[] = new Detail[10];
        for(int c=0; c<details.length; c++)
        {
            details[c]= new Detail("Field_"+c, String.valueOf(c*100));
        }
        
        RuntimeSystem.cobcall("cobprog", new ParameterList().add(new CustomRecordArray(details)));
    }
}



import com.microfocus.cobol.lang.CustomRecord;
import com.microfocus.cobol.lang.ParameterList;


public class Detail implements CustomRecord
{
    private String field1;
    private String field2;
    
    public Detail(String field1, String field2)
    {
        this.field1 = stringFixSize(field1, 20);
        this.field2 = numberFixSize(field2, 10);
    }
    
    private String numberFixSize(String inField, int length)
    {
        /* too big or exact size.. */
        if (inField.length() >= length)
        {
            return inField.substring(0, length);
        }
        
        StringBuilder sb = new StringBuilder();
        for(int c=0; c<length-inField.length(); c++)
        {
            sb.append('0');
        }
        
        sb.append(inField);
        return sb.toString();
    }

    private String stringFixSize(String inField, int length)
    {
        /* too big or exact size.. */
        if (inField.length() >= length)
        {
            return inField.substring(0, length);
        }
        
        StringBuilder sb = new StringBuilder();
        
        sb.append(inField);
        for(int c=0; c<length-inField.length(); c++)
        {
            sb.append(' ');
        }
        return sb.toString();
    }

    @Override
    public Object[] getParameters()
    {
        return new ParameterList().add(field1).add(field2).getArguments();
    }

    @Override
    public void setParameters(Object[] parms)
    {
        this.field1 = (String)parms[0];
        this.field2 = (String)parms[1];
    }

}




g:\java.playground>java -cp "bin;.;%CLASSPATH%" TestDetailsArray
+0000000001 ->Field_0              == 0000000000
+0000000002 ->Field_1              == 0000000100
+0000000003 ->Field_2              == 0000000200
+0000000004 ->Field_3              == 0000000300
+0000000005 ->Field_4              == 0000000400
+0000000006 ->Field_5              == 0000000500
+0000000007 ->Field_6              == 0000000600
+0000000008 ->Field_7              == 0000000700
+0000000009 ->Field_8              == 0000000800

View solution in original post

0 Likes
Absent Member.
Absent Member.
I decompiled the DataTypeArray class in the meantime and affirmed that it concatenates. I also noticed it is not optimal, as that it calls getBytes twice to send data to cobol and once again to retrieve the item class buffer to synchronize from cobol.
As we use generators to create the classes, we created an optimized DataTypeArray.
For other people it would be great to see your example in the demo directory.
0 Likes
The opinions expressed above are the personal opinions of the authors, not of Micro Focus. By using this site, you accept the Terms of Use and Rules of Participation. Certain versions of content ("Material") accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, the Material is now offered by Micro Focus, a separately owned and operated company. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.