simon4

Absent Member.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2012-03-06
08:08
1655 views
[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
1 Solution
Accepted Solutions
spgennard

Micro Focus Expert
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2012-03-07
09:52
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
4 Replies
spgennard

Micro Focus Expert
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2012-03-06
08:18
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.
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.
simon4

Absent Member.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2012-03-06
09:41
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
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
spgennard

Micro Focus Expert
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2012-03-07
09:52
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
simon4

Absent Member.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2012-03-13
09:18
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.
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.