Menu

#33 Duplicate Cobol FieldNames are not allowed for this Template

v1.0_(example)
open
None
1
2022-07-23
2022-06-23
Anonymous
No

Hi Bruce Martin,

I am new to cobol copybook files and exploring things. I am in a need of copybook to java code generation and i am using codegen utility version 0.90.4

I needed your help on couple of things

  1. Import of IArray2Dimension class is missing in net.sf.JRecord.cg.velocity.pojo.Convert.vm when you have multiple occurs, getting a missing import compile error on Convert*.java class, there is only 1D import and if there are more nesting levels needed those many level imports in the import section, please suggest or a provide a fix?

  2. when I have a duplicate fields (it is the case with copybook files in my organization), codegen utility is failing java code generation whereas record editor is generating code with adding running seq number, how can i make this possible using utility ?

sorry cannot share the copybook file for security reason

Thanks well in advance for helping me on this ?

Regards,
Jay

import net.sf.JRecord.cg.Generate;
import net.sf.JRecord.cg.details.ArgumentOption;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CodeGenUtility {

private static Logger logger = LoggerFactory.getLogger(CodeGenUtility.class);

public static void main(String[] mainArgs) {
    String[] args = {
            ArgumentOption.OPT_TEMPLATE, "pojo",
            ArgumentOption.OPT_PACKAGE, "tools.codegen.cb",
            ArgumentOption.OPT_SCHEMA, CodeGenUtility.class.getResource("/copybook/copybook.cbl").getFile(),
            ArgumentOption.OPT_FILE_ORGANISATION, "FixedWidth",
            ArgumentOption.OPT_FONT_NAME, "US-EBCIDIC",
            ArgumentOption.OPT_DIALECT, "Mainframe",
            ArgumentOption.OPT_DROP_COPYBOOK_NAME, "true",
            ArgumentOption.OPT_OUTPUT_DIR, "./src/main/java"
    };

    try {
        Generate.main(args);
    } catch (Exception e) {
        logger.error("Exception while generating java code for copybook ", e);
    }
}

}

Discussion

  • Bruce Martin

    Bruce Martin - 2022-06-23
    • Import of IArray2Dimension class is missing in net.sf.JRecord.cg.velocity.pojo.Convert.vm when you have multiple occurs, getting a missing import compile error on Convert.java class, there is only 1D import and if there are more nesting levels needed those many level imports in the import section, please suggest or a provide a fix? - I will have a look at it*

    • when I have a duplicate fields (it is the case with copybook files in my organization), codegen utility is failing java code generation whereas record editor is generating code with adding running seq number, how can i make this possible using utility ? - You can not, the walker interface may work alternatively the Standard template should work

    Note: you can do

            CodeGenInterface.TEMPLATES.newTempateBuilder(TstIoBldrGen01.class.getResource("DTAR020.cbl").getFile())
                        .setFileOrganisation(FileOrganisation.FIXED_LENGTH)
                        .setCobolDialect(CobolDialects.MAINFRAME)
                        .setCopybookSplitOption(CopybookSplit.SPLIT_NONE)
                        .setFont("cp037")
    

    The Walker interfce may work:

            ICobolIOBuilder ioBuilder = JRecordInterface1.COBOL
                    .newIOBuilder(TstIoBldrGen01.class.getResource("DTAR020.cbl").getFile())
                            .setFileOrganization(IFileStructureConstants.IO_FIXED_LENGTH)
                            .setFont("cp037");
    
            ISchemaWalkerInterface walker = CodeGenInterface.WALKER;
            walker.newBuilder(ioBuilder)
                        .setOutputDirectory("/home/bruce/work/JRecord/CodeGen/walker")
                        .setCobolDataClassPackageName("test.walker.Builder.GenerateCode.data")
                        .setReadClassGenerateParameters(walker.newClassDetailsParam()
                                                            .setPackageName("test.walker.Builder.GenerateCode.example"))
                        .setWriteClassGenerateParameters(walker.newClassDetailsParam()
                                                            .setPackageName("test.walker.Builder.GenerateCode.example"))
                    .generate();
    

    The walker interface is recent experiment, it will generate fields

     
  • Anonymous

    Anonymous - 2022-06-23

    Hi Bruce, Thank you for quick response.

    I am trying your suggestion, I downloaded latest JRecord_CodeGen_0.93.zip

    The following code is having error

    walker.newBuilder(ioBuilder)

    as

    ISchemaWalkerInterface doesnt have the newBuilder() accepting ICobolIOBuilder

    ISchemaWalkerBuilder newBuilder(IGetLayout var1) throws IOException;
    
    ISchemaWalkerBuilder newBuilder(LayoutDetail var1);
    
    ISchemaWalkerBuilder newBuilder(LayoutDef var1);
    
    ISchemaWalkerBuilder newBuilder(ExternalRecord var1) throws IOException;
    
    could you please check ?
    
     
    • Bruce Martin

      Bruce Martin - 2022-06-24

      ICobolIOBuilder should implement IGetLayout . You can do ICobolIOBuilder.getLayout()

       
  • Anonymous

    Anonymous - 2022-06-23

    Hi Bruce,

    My earlier message looks not reached you, I downloaded JRecord_CodeGen_0.93 and trying it but error on walker.newBuilder(), please check

    public void codegenTest() throws Exception {
        ICobolIOBuilder ioBuilder = JRecordInterface1.COBOL
                .newIOBuilder("/copybook/copybook.cbl")
                .setFileOrganization(2)
                .setFont("cp037");
    
        String packagePref = "test.walker.Builder.GenerateCode.dtar020";
        String examplePackage = packagePref + ".example";
        ISchemaWalkerInterface walker = CodeGenInterface.WALKER;
        walker.newBuilder(ioBuilder)
                .setOutputDirectory("CodeGen/walker")
                .setCobolDataClassPackageName(packagePref + ".data")
                .setReadClassGenerateParameters(walker.newClassDetailsParam()
                        .setPackageName(examplePackage))
                .setWriteClassGenerateParameters(walker.newClassDetailsParam()
                        .setPackageName(examplePackage))
                .generate();
    
    }
    
     
  • Bruce Martin

    Bruce Martin - 2022-06-25

    What where the exact errors you where getting ???

    Mapping fields from Cobol to Java is always an issue, the 2 languages are very different.
    Cobol can use

    • Flat naming standard (each field-name is unique, group names are no that important).
    • More hierarchical structure (often the case Group names) are important.

    Another option is to

    1. Create IoBuilder and get the ExternalRecord (method getExternalRecord())
    2. Update Field Names fields with duplicate field names
    3. Use this updated ExternalRecord in CodeGen (May need to use asLayoutDetail() method.
     

    Last edit: Bruce Martin 2022-06-25
  • Anonymous

    Anonymous - 2022-07-12

    Sorry for late reply

    When there is a duplicate filed in the copybook then generation is throwing an error

    Exception in thread "main" java.lang.RuntimeException: Duplicate Cobol FieldNames ar not allowed for this Template
    at net.sf.JRecord.cg.details.GenerateOptions.check4DuplicateFieldNames(GenerateOptions.java:256)
    at net.sf.JRecord.cg.details.GenerateOptions.<init>(GenerateOptions.java:210)
    at net.sf.JRecord.cg.Generate.main(Generate.java:45)</init>

    Standard template works but for me need is to generate pojo out of copybook

    Code is attached here , please help here

     
  • Bruce Martin

    Bruce Martin - 2022-07-23

    I Created a class RenameDuplicates that can rename duplicates within limits (it uses upto 2 group-names to break duplicates.

    In the example below:

    • the schema is read
    • Fields are renamed (new RenameDuplicates(new UpdSchema(externalRecord))
      .updateDuplicateNamesInEachRecord())
    • The pojo's are generated
    • A new Xml Schema is written
            ICobolIOBuilder iob = JRecordInterface1.COBOL.newIOBuilder(new StringReader(cbl), "dup-name")
                    .setFileOrganization(IFileStructureConstants.IO_FIXED_LENGTH)
                    .setFont("cp037");
    
            ExternalRecord externalRecord = iob.getExternalRecord();
    
            List<List<FieldHelper>> dups = new RenameDuplicates(new UpdSchema(externalRecord))
                    .updateDuplicateNamesInEachRecord();
            //System.out.println(dups.size());
    
    
            CodeGenInterface.TEMPLATES.newTempateBuilder(externalRecord.asLayoutDetail())
                    .setTemplate(StandardTemplates.POJO)
                    .setPackageName("dupNames.tst")
                    .setOutputDirectory(outputDir + "/gen")
                    .generateJava();
    
    
            JRecordInterface1.SCHEMA_XML.export(new FileOutputStream(outputDir + "/dup-name.xml"), externalRecord);
    

    To use the generated Pojo's you must use the Xml Schema e.g.

               LineDupNamePojo line;
                IFileIOBuilder iob = JRecordInterface1.SCHEMA_XML.newIOBuilder("/home/bruce/work/CodeGen/Rename/dup-name.xml");
    
                IReader <LineDupNamePojo> reader = new ReadLine<LineDupNamePojo>(
                        iob.newReader("/home/bruce/work/CodeGen/Rename/dupName.txt"), 
                        new ConvertDupName(iob));
    
                while ((line = reader.read()) != null) {
    

    or writing

                IFileIOBuilder iob = JRecordInterface1.SCHEMA_XML.newIOBuilder(schemaStream, "dup-name.xml");
    
                IWriter<LineDupNamePojo> writer = new WriteLine<LineDupNamePojo>(
                        iob.newWriter("/home/bruce/work/CodeGen/Rename/dupName.txt"),
                        new ConvertDupName(iob), 
                        iob.newLine());
    

    The attached source:

    • fieldRename.zip - rename and generate pojo
    • RenameCobolFields.zip - support code.
     

    Last edit: Bruce Martin 2022-07-23

Anonymous
Anonymous

Add attachments
Cancel