I know there is support OCCURS DEPENDING ON in the IOBuilders, but is there a lot of work getting into newCobol2Xml? Is there any plans to do this on the horizon?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have done some basic testing, for a simple occurs depending you should be Ok. For very complicated Occurs Depending (Multiple Nested Occurs Depending) expect problems.
If you decide to use it, I would advise doing your own Tests.
Just following up here from work Brian has done. We have hid an issue with nested OCCURS DEPENDING ON as per the following structure (also attached with some sample data).
I appreciate this is very new functionality and you said to 'expect problems' above but should or could this work ? Either way, I'm happy to check further but would appreciate understanding if I'm looking to fix an issue that should work or whether further work is required.
java.lang.RuntimeException: Error With Occurs Depending On Field: INV-SUB-CT
at net.sf.JRecord.External.Def.DependingOn.updateField(DependingOn.java:151)
at net.sf.JRecord.External.Def.DependingOn.updateField(DependingOn.java:160)
at net.sf.JRecord.Details.RecordDetail.setDependingOn(RecordDetail.java:1100)
at net.sf.JRecord.External.ToLayoutDetail.toRecordDetail(ToLayoutDetail.java:178)
at net.sf.JRecord.External.ToLayoutDetail.getLayout(ToLayoutDetail.java:81)
at net.sf.JRecord.External.ExternalRecord.asLayoutDetail(ExternalRecord.java:1239)
at net.sf.JRecord.schema.CobolSchemaReader.getCobolSchemaDetails(CobolSchemaReader.java:114)
at net.sf.JRecord.cbl2xml.impl.Cobol2GroupXml.doInit(Cobol2GroupXml.java:236)
at net.sf.JRecord.cbl2xml.impl.Cobol2GroupXml.cobol2xml(Cobol2GroupXml.java:183)
at com.jrecord.unit.Test1.test(Test1.java:44)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
JRecord does not handle having the Occurs-Depending size field (INV-SUB-CT) as an array field. Using an
array field like this means Looking the size up for every sub array
There would be a lot of work in supporting it. I will have a think about what is involved in supporting it.
Please understand, nesting the Occurs-Depending size field like this is not in any Cobol Standard,
I recently started a discussion on this at GNU-Cobol:
Note: Array-Checks are not available from the bat interface to CobolToXml.
You must use a JVM language; For example the JavaScript Interpretter (jjs) that comes with Java 8 can be used.
Record Hierarchy
In the latest version, you can create hierarchy between records; see
Understood. Many thanks for the comprehensive feedback. Let me see if we can find a workaround based on your suggestions. Unfortunately we tend to come across non standard stuff like this that 'happens to work' all the time :-(
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Just woke up and thinking a bit more clearly now.
A variation on the Record Hierarch would be to have two records (CUSTOMER && invoice) and keep the SUB-INVOICES occur depending.
It is a very simple Cobol Pseudo Code to convert the file would be:
Read Customer
perform until EOF
Move Cusomer-data to output record.
Write Customer-record
perform varing index from 1 by 1 until index > INVOICE-COUNT
Move Invoice-Data to Invoice-Record
Write Invoice-Record
end-perform
Read Customer
end-perform
Last edit: Bruce Martin 2016-09-16
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
We have a customer who would like us to support this. Would you be open to us implementing and providing the code back to you for review and integration ? If so, have you a view on how long this is likely to take us based on your experience ?
Best regards,
John
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
There are 2 basic related changes I am currently working on
I am splitting some of the classes in the External package (e.g. ExternalRecord) in 2.
The parent (or Base class) will be shared by both JRecord and RecordEditor.
This will reduce the duplicate code I need to maintain and ensure JRecord / RecordEditor
work the same way.
Simplify the Xml-Schema's sou user do not need to enter as much.
Future Changes
At some time in the future I hope to 'Expand' the Occurs-Depending to full size when an Update
is made (this will be for the RecordEditor as much as anything). I was going to implement extended
Occurs-Depending at the same time. This change is at-least a year away.
JRecord Background:
JRecord started as part of the RecordEditor while they are now seperate systems
I keep the 2 systems as close as possible. This allows me to copy code from one system to
the other. It also creates problems:
In JRecord it would make sense to store data/meta-data at the Line Level. In the RecordEditor where you may have millions of Lines you need to avoid storing
meta-data at the line level.
Classes used to represent Occurs-Depending + important methods
There are 2 main classes used to store OccursDepending on detail
DependingOn Is stored in RecordDetail (Schema~Record~Definition class). It represents
a tree of all the Occurs~Depending. There is a DependingOn class for every Occurs-Depending
in the Cobol-Copybook. It has Child-DependingOn representing child occurs depending.
In my working version of JRecord it is Created in BaseCb2XmlLoader;
In older versions of JRecord it was created in XmlCopybookLoader
See attached class
DependingOnDtls Is stored in the FieldDetail (Schema~Field~Definition). It is
bit like TreeNode with a parent-node. Unlike DependingOn; there is a node for every index.
In my working version of JRecord it is Created in BaseCb2XmlLoader;
In older versions of JRecord it was created in XmlCopybookLoader
See attached class
Finally
To make it all work, Field-Definition class (FieldDetail) has a reference back to Record that holds it.
The RecordDetail class has a Method calculateAdjustment which calculates an position adjustment
based on the DependingOn fields
DependingOn class
A Cobol Copybook like
:::Cobol
05 A1 occurs depending on ..
...
07 A11 occurs depending on ..
...
07 A12 occurs depending on ..
is represented as the following tree structure in java
where a Cobol-Occurs-depending is represented as a DependingOn item
with child depending on items if needed
DependingOn
* variableName = A1
+----- DependingOn
| variableName = A11
* children = | children = null
|
+----- DependingOn
variableName = A12
children = null
DependingOnDtls class
This class is held a field level and holds all the index's
For a Cobol Array Field Field-1 (2, 4, 6), you get a structure like:
* DependingOnDtls
* index = 6
* parent = DependingOnDtls
* index = 4
* parent = DependingOnDtls
* index = 2
* parent = null
The method calculateActualPosition (of RecordDetail class) calculates the actual
position of a field taking account of any occurs-depending on clauses
###Java/* (non-Javadoc) * @see net.sf.JRecord.Common.AbstractRecord#calculateActualPosition(net.sf.JRecord.Common.AbstractIndexedLine, net.sf.JRecord.External.Def.DependingOnDtls, int) */@OverridepublicintcalculateActualPosition(AbstractIndexedLineline,DependingOnDtlsdependingOnDtls,intpos){DependingOnDtls[]tree=null;if(dependingOnDtls!=null){tree=dependingOnDtls.getTree();}returnpos-calculateAdjustment(dependingOn,line,tree,0,pos);}/** * Calculate an adjustment to the record Position based on * * @param dependingOnList the list of Depending on clauses to use in the calculation * @param line line or record for which to calculate the position * @param dependingOnDtls depending on details for the field which we are calculating the adjustment for * @param lvl current level (or index in dependingOnDtls array * @param pos position of the field * * @return Adjustment to be made to the field */privateintcalculateAdjustment(List<DependingOn>dependingOnList,finalAbstractIndexedLineline,DependingOnDtls[]dependingOnDtls,intlvl,finalintpos){if(dependingOnList==null||dependingOnList.size()==0||pos<dependingOnList.get(0).getPosition()){return0;}inttmpAdj=0;for(inti=0;i<dependingOnList.size()&&pos>=dependingOnList.get(i).getPosition();i++){DependingOndependingOnDef=dependingOnList.get(i);IFieldDetailfield=dependingOnDef.getField();intadj=0;try{Objectvalue=line.getField(field);List<DependingOn>children=dependingOnDef.getChildren();intactualOccurs=Integer.parseInt(value.toString().trim());intoccursLength=dependingOnDef.getOccursLength();intchildAdjustment=calculateAdjustment(children,line,dependingOnDtls,lvl+1,pos);if(pos>dependingOnDef.getEnd()){intoccursMaxLength=dependingOnDef.getOccursMaxLength();intactualOccursLength=occursLength-childAdjustment;intactualLength=actualOccurs*actualOccursLength;//-calculateAdjustment(dependingOnDef.getChildren(),line,pos);adj=occursMaxLength-actualLength;//calculateAdjustment(dependingOnDef.getChildren(),line,pos);if(pos-adj<dependingOnDef.getPosition()+actualLength){returntmpAdj;}}elseif(children!=null&&children.size()>0&&childAdjustment>0){if(dependingOnDtls!=null&&lvl<dependingOnDtls.length){intidx=dependingOnDtls[lvl].index;adj=childAdjustment*(idx+1);DependingOnc=children.get(children.size()-1);if(pos<c.getEnd()+idx*occursLength){adj=childAdjustment;intoccurs=1;if(occursLength!=0&&pos-c.getEnd()>occursLength){occurs=((int)(pos-c.getEnd())/occursLength)+1;if(occurs>1){adj=childAdjustment*occurs;}}if(pos-children.get(0).getPosition()+children.get(0).getOccursLength()>occursLength){inttChildAdj=calculateAdjustment(children,line,dependingOnDtls,lvl+1,pos-occurs*occursLength);adj+=tChildAdj;}}}else{adj=childAdjustment;}}tmpAdj+=adj;}catch(RuntimeExceptione){System.out.println();System.out.println("ErrorRetrieving:" + (field==null?"nullfield":field.getName())); System.out.println(); throw e; } catch (Exception e) { throw new RecordException("ErrorcalculationOccursDependingOnforVariable:" + dependingOnDef.getVariableName() + "msg="+e.getMessage(),e);}}returntmpAdj;}
I will update DependingOn (and the code that updates it) in two several ways
stop the exception bbeing thrown
Add a flag's to indicate there are occurs-depending fields in arrays like this case
Some method of getting the field
Currently currently the calculateAdjustment in the RecordDetail calculates the
adjustment for Occurs-Depending array fields. I am suggesting using the Stratergy pattern
and having three class (with calculateAdjustment methods)
Once class for when there are no occurs depending fields, calculateAdjustment would return 0.
One class that uses the current calculateAdjustment method for standard occurs-depending on
A new class for the complicated occurs-depending
Using a stratergy pattern will mean:
you do not need to worry about JRecord internals as much
It can be worked on independently to JRecord and implemented in ready.
A couple other comments
To avoid doing the same calculations over and aver again it might be worth while
saving calculations between calls to calculateAdjustment. It depends on the cost of the
calculations against doing a HashMap lookup.
I have done some testing on 2 level Complex OD like in the Copybook above.
It would be useful If some one could check check against real Live files as I do not have any. There are more changes and Testing before I do a full release of the JRecord
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have built jrecord successfully but I can't see a pom.xml in the CobolToXml/Version_0.81.3/, only a build.xml and I'm afraid I'm not familiar with ant. Or am I missing something ?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Just wanted to be sure I wasn't missing something. I'll try to put one together today.....hopefully the dependencies will be obvious from the build.xml
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Attached is what I came up with but I couldn't work out where the missing dependencies are. This is the output from the package. Any advice on what I have screwed up welcome :-)
C:\Users\jpo\Downloads\CobolToXml_0.81.3\Source\CobolToXml>mvn clean install [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building CobolToXml 0.81.1 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ CobolToXml --- [INFO] Deleting C:\Users\jpo\Downloads\CobolToXml_0.81.3\Source\CobolToXml\target [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ CobolToXml --- [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory C:\Users\jpo\Downloads\CobolToXml_0.81.3\Source\CobolToXml\src\main\resources [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ CobolToXml --- [INFO] Changes detected - recompiling the module! [WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. build is platform dependent! [INFO] Compiling 41 source files to C:\Users\jpo\Downloads\CobolToXml_0.81.3\Source\CobolToXml\target\classes [INFO] ------------------------------------------------------------- [ERROR] COMPILATION ERROR : [INFO] ------------------------------------------------------------- [ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/Cobol2GroupXml.java:[54,31] cannot find symbol
symbol: class ICobolCopybookLoader
location: package net.sf.JRecord.External [ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/Cobol2GroupXml.java:[96,57] cannot find symbol
symbol: class ICobolCopybookLoader
location: class net.sf.JRecord.cbl2xml.impl.Cobol2GroupXml [ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/Cobol2GroupXml.java:[103,69] cannot find symbol
symbol: class ICobolCopybookLoader
location: class net.sf.JRecord.cbl2xml.impl.Cobol2GroupXml [ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/Cobol2GroupXml.java:[111,76] cannot find symbol
symbol: class ICobolCopybookLoader
location: class net.sf.JRecord.cbl2xml.impl.Cobol2GroupXml [ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/ZOldCobol2GroupXml.java:[58,31] cannot find symbol
symbol: class Cb2xmlDocument
location: package net.sf.JRecord.External [ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/ZOldCobol2GroupXml.java:[62,31] cannot find symbol
symbol: class ICobolCopybookLoader
location: package net.sf.JRecord.External [ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/ZOldCobol2GroupXml.java:[111,61] cannot find symbol
symbol: class ICobolCopybookLoader
location: class net.sf.JRecord.cbl2xml.impl.ZOldCobol2GroupXml [ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/ZOldCobol2GroupXml.java:[118,73] cannot find symbol
symbol: class ICobolCopybookLoader
location: class net.sf.JRecord.cbl2xml.impl.ZOldCobol2GroupXml [ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/ZOldCobol2GroupXml.java:[126,80] cannot find symbol
symbol: class ICobolCopybookLoader
location: class net.sf.JRecord.cbl2xml.impl.ZOldCobol2GroupXml [ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/ZOldCobol2GroupXml.java:[272,46] cannot find symbol
symbol: class Cb2xmlDocument
location: class net.sf.JRecord.cbl2xml.impl.ZOldCobol2GroupXml [INFO] 10 errors [INFO] ------------------------------------------------------------- [INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 3.025 s [INFO] Finished at: 2016-10-19T10:45:56+01:00 [INFO] Final Memory: 14M/172M [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project CobolToXml: Compilation failure: Compilation failure: [ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/Cobol2GroupXml.java:[54,31] cannot find symbol [ERROR] symbol: class ICobolCopybookLoader [ERROR] location: package net.sf.JRecord.External [ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/Cobol2GroupXml.java:[96,57] cannot find symbol [ERROR] symbol: class ICobolCopybookLoader [ERROR] location: class net.sf.JRecord.cbl2xml.impl.Cobol2GroupXml [ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/Cobol2GroupXml.java:[103,69] cannot find symbol [ERROR] symbol: class ICobolCopybookLoader [ERROR] location: class net.sf.JRecord.cbl2xml.impl.Cobol2GroupXml [ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/Cobol2GroupXml.java:[111,76] cannot find symbol [ERROR] symbol: class ICobolCopybookLoader [ERROR] location: class net.sf.JRecord.cbl2xml.impl.Cobol2GroupXml [ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/ZOldCobol2GroupXml.java:[58,31] cannot find symbol [ERROR] symbol: class Cb2xmlDocument [ERROR] location: package net.sf.JRecord.External [ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/ZOldCobol2GroupXml.java:[62,31] cannot find symbol [ERROR] symbol: class ICobolCopybookLoader [ERROR] location: package net.sf.JRecord.External [ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/ZOldCobol2GroupXml.java:[111,61] cannot find symbol [ERROR] symbol: class ICobolCopybookLoader [ERROR] location: class net.sf.JRecord.cbl2xml.impl.ZOldCobol2GroupXml [ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/ZOldCobol2GroupXml.java:[118,73] cannot find symbol [ERROR] symbol: class ICobolCopybookLoader [ERROR] location: class net.sf.JRecord.cbl2xml.impl.ZOldCobol2GroupXml [ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/ZOldCobol2GroupXml.java:[126,80] cannot find symbol [ERROR] symbol: class ICobolCopybookLoader [ERROR] location: class net.sf.JRecord.cbl2xml.impl.ZOldCobol2GroupXml [ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/ZOldCobol2GroupXml.java:[272,46] cannot find symbol [ERROR] symbol: class Cb2xmlDocument [ERROR] location: class net.sf.JRecord.cbl2xml.impl.ZOldCobol2GroupXml [ERROR] -> [Help 1] [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please read the following articles: [ERROR][Help 1]http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
Hi Bruce,
I know there is support OCCURS DEPENDING ON in the IOBuilders, but is there a lot of work getting into newCobol2Xml? Is there any plans to do this on the horizon?
I have already started work on it; will let you know how it goes
I have updated subversion.
I have done some basic testing, for a simple occurs depending you should be Ok. For very complicated Occurs Depending (Multiple Nested Occurs Depending) expect problems.
If you decide to use it, I would advise doing your own Tests.
I have also uplodaed updated jars here
Great, thanks a lot. Will check it out over the next few days.
It really needs more testing, but that involves writing simple programs to create files then setting up the tests. It all takes time
I have done some more Testing; looks good so far.
Extra Tests have been uploaded to subversion
Bruce,
Just following up here from work Brian has done. We have hid an issue with nested OCCURS DEPENDING ON as per the following structure (also attached with some sample data).
I appreciate this is very new functionality and you said to 'expect problems' above but should or could this work ? Either way, I'm happy to check further but would appreciate understanding if I'm looking to fix an issue that should work or whether further work is required.
Best regards,
John
This results in the following error:
java.lang.RuntimeException: Error With Occurs Depending On Field: INV-SUB-CT
at net.sf.JRecord.External.Def.DependingOn.updateField(DependingOn.java:151)
at net.sf.JRecord.External.Def.DependingOn.updateField(DependingOn.java:160)
at net.sf.JRecord.Details.RecordDetail.setDependingOn(RecordDetail.java:1100)
at net.sf.JRecord.External.ToLayoutDetail.toRecordDetail(ToLayoutDetail.java:178)
at net.sf.JRecord.External.ToLayoutDetail.getLayout(ToLayoutDetail.java:81)
at net.sf.JRecord.External.ExternalRecord.asLayoutDetail(ExternalRecord.java:1239)
at net.sf.JRecord.schema.CobolSchemaReader.getCobolSchemaDetails(CobolSchemaReader.java:114)
at net.sf.JRecord.cbl2xml.impl.Cobol2GroupXml.doInit(Cobol2GroupXml.java:236)
at net.sf.JRecord.cbl2xml.impl.Cobol2GroupXml.cobol2xml(Cobol2GroupXml.java:183)
at com.jrecord.unit.Test1.test(Test1.java:44)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Last edit: Bruce Martin 2016-09-15
JRecord does not handle having the Occurs-Depending size field (INV-SUB-CT) as an array field. Using an
array field like this means Looking the size up for every sub array
There would be a lot of work in supporting it. I will have a think about what is involved in supporting it.
Please understand, nesting the Occurs-Depending size field like this is not in any Cobol Standard,
I recently started a discussion on this at GNU-Cobol:
If sole purpose of the copybook is to create Xml; there are two other ways to handle this (in the latest version at CobolToXml
Array-Checks
See the attached HTML. Basically replace the second occurs depending with a straight Occurs:
In Cobol move spaces (or low values) to the empty SUB-INVOICES-DATA fields
In Java / Java-Script / Groovy / Any-JVM language set an Array Check Line:
Note: Array-Checks are not available from the bat interface to CobolToXml.
You must use a JVM language; For example the JavaScript Interpretter (jjs) that comes with Java 8 can be used.
Record Hierarchy
In the latest version, you can create hierarchy between records; see
In this case you would have 3 records
Copybook becomes:
And the Xml Generate Command becomes:
Doing it this way there are no issues with array limits. It is
worthing knowing this for future reference.
Understood. Many thanks for the comprehensive feedback. Let me see if we can find a workaround based on your suggestions. Unfortunately we tend to come across non standard stuff like this that 'happens to work' all the time :-(
Just woke up and thinking a bit more clearly now.
A variation on the Record Hierarch would be to have two records (CUSTOMER && invoice) and keep the SUB-INVOICES occur depending.
It is a very simple Cobol Pseudo Code to convert the file would be:
Last edit: Bruce Martin 2016-09-16
Thanks for this.Sounds like a very reasonable approach.
Bruce,
We have a customer who would like us to support this. Would you be open to us implementing and providing the code back to you for review and integration ? If so, have you a view on how long this is likely to take us based on your experience ?
Best regards,
John
I have no problem with your proposal.
Tommorow morning I will have a look and think about it prepare some basic notes / explanation
of the Occurs Depending code.
Sounds good. I'd appreciate a heads up on any standards, policies etc. you have for the code so that we can adhere to them.
Background
My current changes:
There are 2 basic related changes I am currently working on
The parent (or Base class) will be shared by both JRecord and RecordEditor.
This will reduce the duplicate code I need to maintain and ensure JRecord / RecordEditor
work the same way.
Future Changes
is made (this will be for the RecordEditor as much as anything). I was going to implement extended
Occurs-Depending at the same time. This change is at-least a year away.
JRecord Background:
JRecord started as part of the RecordEditor while they are now seperate systems
I keep the 2 systems as close as possible. This allows me to copy code from one system to
the other. It also creates problems:
In JRecord it would make sense to store data/meta-data at the Line Level. In the
RecordEditor where you may have millions of Lines you need to avoid storing
meta-data at the line level.
Classes used to represent Occurs-Depending + important methods
There are 2 main classes used to store OccursDepending on detail
DependingOn Is stored in RecordDetail (Schema~Record~Definition class). It represents
a tree of all the Occurs~Depending. There is a DependingOn class for every Occurs-Depending
in the Cobol-Copybook. It has Child-DependingOn representing child occurs depending.
DependingOnDtls Is stored in the FieldDetail (Schema~Field~Definition). It is
bit like TreeNode with a parent-node. Unlike DependingOn; there is a node for every index.
Finally
The RecordDetail class has a Method calculateAdjustment which calculates an position adjustment
based on the DependingOn fields
DependingOn class
A Cobol Copybook like
:::Cobol
05 A1 occurs depending on ..
...
07 A11 occurs depending on ..
...
07 A12 occurs depending on ..
is represented as the following tree structure in java
where a Cobol-Occurs-depending is represented as a DependingOn item
with child depending on items if needed
DependingOnDtls class
This class is held a field level and holds all the index's
For a Cobol Array Field Field-1 (2, 4, 6), you get a structure like:
Basically an item represents one index.
calculateAdjustment method (of RecordDetail class)
The method calculateActualPosition (of RecordDetail class) calculates the actual
position of a field taking account of any occurs-depending on clauses
Code changes proposal
I will update DependingOn (and the code that updates it) in two several ways
Currently currently the calculateAdjustment in the RecordDetail calculates the
adjustment for Occurs-Depending array fields. I am suggesting using the Stratergy pattern
and having three class (with calculateAdjustment methods)
Using a stratergy pattern will mean:
A couple other comments
To avoid doing the same calculations over and aver again it might be worth while
saving calculations between calls to calculateAdjustment. It depends on the cost of the
calculations against doing a HashMap lookup.
also a Cobol Copybook like
May cause problems; the DependingOnDtls class structure may need to be enhanced
Code style, basically I can live with the Sun/Oracle type style
Bascally I use { at the end of the lines like
If going over more than one line, I tend to do
or
basically I am not to fussy on code style.
The other thing is Unit Tests
I will look a bit more tommorow
Thanks. Let me absorb this and take a look at the code and ensure I understand where you are coming from here.
I have started work on supporting
Complex Occurs Depending
, there is a new version of JRecord:This should work with the last Cobol2Xml:
I have done some testing on 2 level Complex OD like in the Copybook above.
It would be useful If some one could check check against real
Live
files as I do not have any. There are more changes and Testing before I do a full release of the JRecordI have just released JRecord 0.81.3 with Extended Occurs Depending Support
Forgot to mention CobolToXml can be downloaded from:
Sorry, I got distracted and the urgency from the customer seemed to wane a little. We can pick this up and test over the coming weeks I'd expect.
I have built jrecord successfully but I can't see a pom.xml in the CobolToXml/Version_0.81.3/, only a build.xml and I'm afraid I'm not familiar with ant. Or am I missing something ?
I guess I need to create one
Just wanted to be sure I wasn't missing something. I'll try to put one together today.....hopefully the dependencies will be obvious from the build.xml
Attached is what I came up with but I couldn't work out where the missing dependencies are. This is the output from the package. Any advice on what I have screwed up welcome :-)
C:\Users\jpo\Downloads\CobolToXml_0.81.3\Source\CobolToXml>mvn clean install
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building CobolToXml 0.81.1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ CobolToXml ---
[INFO] Deleting C:\Users\jpo\Downloads\CobolToXml_0.81.3\Source\CobolToXml\target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ CobolToXml ---
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory C:\Users\jpo\Downloads\CobolToXml_0.81.3\Source\CobolToXml\src\main\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ CobolToXml ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. build is platform dependent!
[INFO] Compiling 41 source files to C:\Users\jpo\Downloads\CobolToXml_0.81.3\Source\CobolToXml\target\classes
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/Cobol2GroupXml.java:[54,31] cannot find symbol
symbol: class ICobolCopybookLoader
location: package net.sf.JRecord.External
[ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/Cobol2GroupXml.java:[96,57] cannot find symbol
symbol: class ICobolCopybookLoader
location: class net.sf.JRecord.cbl2xml.impl.Cobol2GroupXml
[ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/Cobol2GroupXml.java:[103,69] cannot find symbol
symbol: class ICobolCopybookLoader
location: class net.sf.JRecord.cbl2xml.impl.Cobol2GroupXml
[ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/Cobol2GroupXml.java:[111,76] cannot find symbol
symbol: class ICobolCopybookLoader
location: class net.sf.JRecord.cbl2xml.impl.Cobol2GroupXml
[ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/ZOldCobol2GroupXml.java:[58,31] cannot find symbol
symbol: class Cb2xmlDocument
location: package net.sf.JRecord.External
[ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/ZOldCobol2GroupXml.java:[62,31] cannot find symbol
symbol: class ICobolCopybookLoader
location: package net.sf.JRecord.External
[ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/ZOldCobol2GroupXml.java:[111,61] cannot find symbol
symbol: class ICobolCopybookLoader
location: class net.sf.JRecord.cbl2xml.impl.ZOldCobol2GroupXml
[ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/ZOldCobol2GroupXml.java:[118,73] cannot find symbol
symbol: class ICobolCopybookLoader
location: class net.sf.JRecord.cbl2xml.impl.ZOldCobol2GroupXml
[ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/ZOldCobol2GroupXml.java:[126,80] cannot find symbol
symbol: class ICobolCopybookLoader
location: class net.sf.JRecord.cbl2xml.impl.ZOldCobol2GroupXml
[ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/ZOldCobol2GroupXml.java:[272,46] cannot find symbol
symbol: class Cb2xmlDocument
location: class net.sf.JRecord.cbl2xml.impl.ZOldCobol2GroupXml
[INFO] 10 errors
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.025 s
[INFO] Finished at: 2016-10-19T10:45:56+01:00
[INFO] Final Memory: 14M/172M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project CobolToXml: Compilation failure: Compilation failure:
[ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/Cobol2GroupXml.java:[54,31] cannot find symbol
[ERROR] symbol: class ICobolCopybookLoader
[ERROR] location: package net.sf.JRecord.External
[ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/Cobol2GroupXml.java:[96,57] cannot find symbol
[ERROR] symbol: class ICobolCopybookLoader
[ERROR] location: class net.sf.JRecord.cbl2xml.impl.Cobol2GroupXml
[ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/Cobol2GroupXml.java:[103,69] cannot find symbol
[ERROR] symbol: class ICobolCopybookLoader
[ERROR] location: class net.sf.JRecord.cbl2xml.impl.Cobol2GroupXml
[ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/Cobol2GroupXml.java:[111,76] cannot find symbol
[ERROR] symbol: class ICobolCopybookLoader
[ERROR] location: class net.sf.JRecord.cbl2xml.impl.Cobol2GroupXml
[ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/ZOldCobol2GroupXml.java:[58,31] cannot find symbol
[ERROR] symbol: class Cb2xmlDocument
[ERROR] location: package net.sf.JRecord.External
[ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/ZOldCobol2GroupXml.java:[62,31] cannot find symbol
[ERROR] symbol: class ICobolCopybookLoader
[ERROR] location: package net.sf.JRecord.External
[ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/ZOldCobol2GroupXml.java:[111,61] cannot find symbol
[ERROR] symbol: class ICobolCopybookLoader
[ERROR] location: class net.sf.JRecord.cbl2xml.impl.ZOldCobol2GroupXml
[ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/ZOldCobol2GroupXml.java:[118,73] cannot find symbol
[ERROR] symbol: class ICobolCopybookLoader
[ERROR] location: class net.sf.JRecord.cbl2xml.impl.ZOldCobol2GroupXml
[ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/ZOldCobol2GroupXml.java:[126,80] cannot find symbol
[ERROR] symbol: class ICobolCopybookLoader
[ERROR] location: class net.sf.JRecord.cbl2xml.impl.ZOldCobol2GroupXml
[ERROR] /C:/Users/jpo/Downloads/CobolToXml_0.81.3/Source/CobolToXml/src/net/sf/JRecord/cbl2xml/impl/ZOldCobol2GroupXml.java:[272,46] cannot find symbol
[ERROR] symbol: class Cb2xmlDocument
[ERROR] location: class net.sf.JRecord.cbl2xml.impl.ZOldCobol2GroupXml
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
C:\Users\jpo\Downloads\CobolToXml_0.81.3\Source\CobolToXml>