Prev Up Next

Extending the Record Editor

The RecordEditor can be extended in a number of ways:

All these examples require you update a Table in the Layout Editor


Editting a Table in the LayoutEditor

After starting the LayoutEdit, the menu screen is displayed:

Click on the second option Edit Tables and the Table edit screen is displayed:

You can select a table to be updated by clicking on the Table in the list on the left.


Type Interface

A `Type` acts as an interface between the fields storage in the data record and how it is displayed on the screen. It contains methods to extract a field from the data record (getField) and store it back in the data record

 83:    /**
 84:     * Extracts a field out of a data record
 85:     *
 86:     * @param data record which is to have the field extracted
 87:     * @param position position in the record
 88:     * @param currField Field Details
 89:     *
 90:     * @return the request field (formated)
 91:     */
 92:    public abstract Object getField(final byte[] data,
 93:                                    final int position,
 94:                                    final FieldDetail currField);
 95:
 96:
 97:    /**
 98:     * Sets a field to a new value in the supplied data record
 99:     *
100:     * @param data record which is to be update
101:     * @param position position in the record
102:     * @param field Field Details
103:     * @param val new value
104:     *
105:     * @return updated record
106:     * @throws RecordException any error that occurs during the save
107:     */
108:    public abstract byte[] setField(final byte[] data,
109:                                  final int position,
110:                                  final FieldDetail field,
111:                                  Object val)
112:    throws RecordException;
113:
114:    /**
115:     * Format a value for storing in the record, it
116:     * has 3 uses
117:     * <ol compact>
118:     *  <li>Format the string for storing in a record.
119:     *  <li>Format for storing as a String in a comma / tab delimited files.
120:     *  <li>Validate a value
121:     * </ol>
122:     *
123:     * @param field field definition
124:     * @param val value to be formated
125:     *
126:     * @return value value as it is store in the record
127:     * @throws RecordException any conversion errors
128:     */
129:    public abstract String formatValueForRecord(FieldDetail field, String val)
130:    throws RecordException;
131:
132:
133:    /**
134:     * wether it is a binary field
135:     *
136:     * @return wether it is binary field
137:     */
138:    public abstract boolean isBinary();
139:
140:    /**
141:     * Get the type of field
142:     * @return type of field
143:     */
144:    public abstract int getFieldType();


CellFormat Interface

A `CellFormat` provides TableCellRenderer's and TableCellEditor's to the RecordEditor. A CellFormat added to the system as part of a Type or as a separately as Formats.

   1:    /**
   2:     * Get Table Cell Render
   3:     * <b>Note:</b> you should always return a new Editor rather than a
   4:     * the same editor each time
   5:     *
   6:     * @param fld field being displayed
   7:     *
   8:     * @return Table Cell Render to be used to display the field
   9:     */
  10:    public abstract TableCellRenderer getTableCellRenderer(FieldDetail fld);
  11:
  12:    /**
  13:     * Get Table Cell Editor
  14:     *
  15:     * @param fld field being displayed
  16:     *
  17:     * @return Table Cell Editor to be used to edit the field
  18:     */
  19:    public abstract TableCellEditor getTableCellEditor(FieldDetail fld);
  20:
  21:
  22:    /**
  23:     * Get the normal width of a field
  24:     *
  25:     * @return field width
  26:     */
  27:    public abstract int getFieldWidth();
  28:
  29:
  30:    /**
  31:     * Get the normal height of a field
  32:     *
  33:     * @return field height
  34:     */
  35:    public abstract int getFieldHeight();
  36:


TypeManager

The TypeManager is used store the Type's and CellFormat's. You can use the static method getSystemTypeManager to get the system TypeManager.

   1:        TypeManager typeManager = TypeManager.getSystemTypeManager();
   2:

Initially the TypeManager allows user types and user Cell Formats to have Id's of 1000 -> 1050. You can increase the number of User Types/Cell Formats via the setSystemTypeManager method.

   1:        TypeManager.setSystemTypeManager(new TypeManager(true, 200, 100));

You can define a type to a TypeManager by

   1:            typeManager.registerType(1000, checkBox);
   2:

Alternatively you can also assign a CellFormat to a Type as well by

   1:            typeManager.registerType(1000, checkBox, checkBox);
   2:


Adding a Type to the RecordEditor

Create the Type (new method)

Jave code for US Date Type

Following is the java code to implement a US Style MM/DD/YY date.

   1:package net.sf.RecordEditor.examples;
   2:
   3:import net.sf.RecordEditor.record.types.TypeChar;
   4:import net.sf.RecordEditor.record.types.TypeDateWrapper;
   5:
   6:/**
   7: * provide a US style date (mm/dd/yy)
   8: *
   9: * @author Bruce Martin
  10: *
  11: */
  12:public class USdate8 extends TypeDateWrapper {
  13:
  14:    /**
  15:     * provide a US style date (mm/dd/yy)
  16:     */
  17:    public USdate8() {
  18:        super(new TypeChar(true), "MM/dd/yy");
  19:    }
  20:}

Following is the code to provide a special Date Editor

   1:package net.sf.RecordEditor.examples;
   2:
   3:import net.sf.RecordEditor.record.format.DateFormat;
   4:
   5:/**
   6: * US date cell format (MM/DD/YY)
   7: *
   8: * @author Bruce Martin
   9: *
  10: */
  11:public class USdateFormat8 extends DateFormat {
  12:
  13:    /**
  14:     * US date cell format (MM/DD/YY)
  15:     */
  16:    public USdateFormat8() {
  17:        super(true, "MM/dd/yy");
  18:    }
  19:}
  20:

You now need to bundle this Type as a Java Jar file.

Defining a Type to the RecordEditor

Start the Edit RecordEditor Startup Properties and go to the User Types tag and entor the new Type as in the diagram below:

The next step is to define where your type is found, so go to the User Jars tag an enter your new jar as below

You can now use the new Type in both the RecordEditor and the LayoutEditor.

Create the Type (old method)

The first step is the type (examples are TypeCheckBoxYN.Java and TypeComboExample.Java)

   3:    public class TypeCheckBoxYN implements Type, CellFormat {
   4:
        ....    Type Code goes here    .....
   5:
   6:    }

Defining a Type to the RecordEditor

There are 2 ways to define a Type to the RecordEditor

  1. Via the Edit RecordEditor Startup Properties program

  2. Via the old method

Define the Type in the LayoutEditor  Next step is to define the Type to the RecordEditor. This is done in table 1, the Type table (go into LayoutEdit, take option 2 Edit Tables. See "Editting a Table in the LayoutEditor" for details). In the picture below, a new user type 1001 ~ Checkbox Y/N has been defined

Using the new Type  You should now be able to use the Type Checkbox Y/N in the field definition panel (Record Definition screen) as below.

Starting the RecordEditor with the new Type  The final step is to start the RecordEditor with the new Type. Please note that at line 9, the new type checkBox is defined as type number 1001, which is exactly the same as what it was defined in the LayoutEdit (see "Define the Type in the LayoutEditor").

   1:
   2:        TypeManager typeManager    = TypeManager.getSystemTypeManager();
   3:        CopyBookDbReader copybook  = new CopyBookDbReader();
   4:        TypeCheckBoxYN checkBox    = new TypeCheckBoxYN();
   5:        TypeComboExample typeCombo = new TypeComboExample();
   6:
   7:        try {
   8:            // register the new types  with the type manager
   9:            typeManager.registerType(1001, checkBox, checkBox);
  10:            typeManager.registerType(1002, typeCombo, typeCombo);
  11:
  12:            new EditRec("", 1, copybook); // starting the record editor
  13:
  14:        } catch (Exception e) {
  15:            e.printStackTrace();
  16:        }
  17:

This java code came from XmplType1.Java

Editing a File

Finally after starting the editor using the java code from "Starting the RecordEditor with the new Type", it should like (with Combobox's and Checkbox's).

or the record view


Adding a Format to the RecordEditor

This section goes through adding and then using a "Adding a Format to the RecordEditor" in the RecordEdit.

Writing a format

The following code was extracted from FormatComboExample.java

33:public class XmplEditSpecificFile1 {
34:
35:    private static String filename   = Constants.EXAMPLE_FILE_DIRECTORY
36:                                     + "Ams_LocDownload_20041228.txt";
37:    private static String layoutName = "ams Store";
38:    private static int initialRow = 0;
39:
40:    /**
41:     * This is an example of editing a specific file
42:     * (without displaying the RecordEditor File selection screen)
43:     *
44:     * @param args program args
45:     */
46:    public static void main(String[] args) {
47:        CopyBookDbReader copyBookInterface = new CopyBookDbReader();
48:        LayoutDetail fileDescription = copyBookInterface.getLayout(layoutName);
49:
50:        if (fileDescription == null) {
51:            System.out.println(
52:                "Record Layout \"" + layoutName + "\" not loaded: "
53:                + copyBookInterface.getMessage());
54:        } else {
55:            try {
56:                FileView file = new FileView(filename,
57:                                       fileDescription,
58:                                       false);
59:
60:                new ReMainFrame("Specific file", "");
61:                LineList list = new LineList(fileDescription, file, file);
62:                list.setCurrRow(initialRow, -1, -1);
63:                list.addInternalFrameListener(new InternalFrameAdapter() {
64:                    public void internalFrameClosed(final InternalFrameEvent e) {
65:                        Common.closeConnection();
66:
67:                        System.exit(0);
68:                    }
69:                });
70:
71:            } catch (Exception e) {
72:                e.printStackTrace();
73:            }
74:        }
75:    }
76:}

Define the Format in the LayoutEditor

Next step is to define the Format in the Format Table (go into LayoutEdit, take option 2 Edit Tables, finally click on Table 5 ~ Formats. See "Editting a Table in the LayoutEditor" for details) and enter the new format (in this case 1001 ~ ComboBox).

Using the new Format

You should now be able to use the format Combobox in Record field definitions.

Starting the RecordEditor with the new Type

The final step is to start the RecordEditor with the new Format. Please note

  1. On line 12, the Combo Items are registered against AMS PO Type which is the field Parameter in "Using the new Format"
  2. On line 15, the comboFormat is defined to the system with a key of 1001, which was also used in "Define the Format in the LayoutEditor".

   1:        String[][] AMS_PO_ITEMS = {
   2:                {"H1", "Header Record"},
   3:                {"D1", "Product Record"},
   4:                {"S1", "Allocation Record"},
   5:        };
   6:
   7:        TypeManager        typeManager = TypeManager.getSystemTypeManager();
   8:        CopyBookDbReader      copybook = new CopyBookDbReader();
   9:        FormatComboExample comboFormat = new FormatComboExample();
  10:
  11:                //   Register Combo Details
  12:        comboFormat.register("AMS PO Type", AMS_PO_ITEMS);
  13:
  14:        try {
  15:                // register the new types  with the type manager
  16:            typeManager.registerFormat(1001, comboFormat);
  17:
  18:            new EditRec("", 1, copybook); // starting the record editor
  19:
  20:        } catch (Exception e) {
  21:

Editing a File

Finally after starting the editor using the java code from "Starting the RecordEditor with the new Type"


Record Deciders

When there are more than one Record in a Layout, there has to be a way to decide which record should be used. One way of doing this is via a RecordDecider:

   1:public interface RecordDecider {
   2:
   3:    /**
   4:     * Get the prefered Layout
   5:     *
   6:     * @param line to decide what the prefered layout is
   7:     *
   8:     * @return the prefered layout
   9:     */
  10:    public abstract int getPreferedIndex(Line line);
  11:}

Once you have created a RecordDecider, you must register it and start the Editor as follows (example taken from XmplDecider.java):

   1:        CopyBookDbReader copybook = new CopyBookDbReader();
   2:
   3:        copybook.registerDecider("ProductExmpl", new XmplDecider());
   4:
   5:        new EditRec("", 1, copybook);


Adding a File Structure

To add a new file structure, you must:

  1. Create a Line-Reader (must extend class AbsLineReader) and Line-Writer (must extend class AbsLineWriter).
  2. Define the new File Structure in the File Structure Table. See "Editting a Table in the LayoutEditor" for details.
  3. Create a new LineIOProvider that uses the new Line-Reader and Line-Writer.
  4. Call the RecordEditor with the new LineIOProvider

Line Reader

To create a new file structure, you must create a new LineReader that extends the class AbsLineReader and implements the abstract methods open, read and close.

   1:    /**
   2:     * Open file for input
   3:     * @param inputStream input stream to be read
   4:     * @param pLayout record layout
   5:     * @throws IOException any IOerror
   6:     */
   7:    public abstract void open(InputStream inputStream, LayoutDetail pLayout)
   8:    throws IOException;
   9:
  10:
  11:
  12:    /**
  13:     * Read one line from the input file
  14:     * @return line read in
  15:     * @throws IOException io error
  16:     */
  17:    public abstract Line read() throws IOException;
  18:
  19:
  20:    /**
  21:     * Closes the file
  22:      * @throws IOException io error
  23:     */
  24:    public abstract void close() throws IOException;
  25:

Line Writer

You must also create a new LineWriter that extends the class AbsLineWriter and implements the abstract methods open, write and close.

   1:   /**
   2:     * Open file for input
   3:     * @param outputStream input stream to write
   4:     * @throws IOException any IOerror
   5:     */
   6:    public abstract void open(OutputStream outputStream)
   7:    throws IOException;
   8:
   9:
  10:    /**
  11:     * Read one line from the input file
  12:     * @param line line to write to the output file
  13:     * @throws IOException any IOerror
  14:     */
  15:    public abstract void write(Line line) throws IOException;
  16:
  17:
  18:    /**
  19:     * Closes the file
  20:     * @throws IOException any IOerror
  21:     */
  22:    public abstract void close() throws IOException;
  23:

Defining the File Structure in the LayoutEditor

The next step is to add the new file structure to the File Structure table. See "Editting a Table in the LayoutEditor" for details.

Using the new File Structure

You should now be able to use the new file structure in the Record-Definition Extra panel:

Creating a LineIOProvider

Following is a sample LineIOProvider that will create the new LineReader's / LineReader's if the appropriate file structure is supplied.

   1:public class XmplFileStructure2 extends LineIOProvider {
   2:
   3:    private static final int MY_FILE_STRUCTURE = 1002;
   4:
   5:    /**
   6:     * get LineReader for the supplied
   7:     */
   8:    public AbsLineReader getLineReader(int fileStructure) {
   9:
  10:        if (fileStructure == MY_FILE_STRUCTURE) {
  11:            return new DelimLineReader(super.getLineProvider());
  12:        }
  13:        return super.getLineReader(fileStructure);
  14:    }
  15:
  16:
  17:    /**
  18:     * get LineWriter for the supplied structure
  19:     */
  20:    public AbsLineWriter getLineWriter(int fileStructure) {
  21:
  22:        if (fileStructure == MY_FILE_STRUCTURE) {
  23:            return new DelimLineWriter();
  24:        }
  25:        return super.getLineWriter(fileStructure);
  26:    }
  27:

Starting the RecordEditor

The following code starts the RecordEditor with the LineIOProvider from "Creating a LineIOProvider". This will introduce the new File Structures.

   1:        CopyBookDbReader copybook = new CopyBookDbReader();
   2:
   3:        new EditRec("", 1, new XmplFileStructure2(), copybook);
   4:

Examples

See XmplFileStructure1.java and XmplFileStructure2.java for examples.


Copybook Loader

If you already have record layouts (Copybooks in Cobol), you should look at the writing your own CopybookLoader. This will allow you to import the record layouts into the RecordEditor as well as use the layouts in the Cobol Editor program

CopybookLoader Interface

The CopybookLoader Interface describes a class to load a external Record Layout into the RecordEditor's internal DB.

20:/**
21: * description of a class to load a copybook
22: *
23: * @author Bruce Martin
24: *
25: */
26:public interface CopybookLoader {
27:
28:    public static final int FMT_INTEL      = 0;
29:    public static final int FMT_MAINFRAME  = 1;
30:    public static final int FMT_BIG_ENDIAN = 1;
31:    public static final int FMT_FUJITSU    = 2;
32:
33:    public static final int SPLIT_NONE     = 0;
34:    public static final int SPLIT_REDEFINE = 1;
35:    public static final int SPLIT_01_LEVEL = 2;
36:
37:    /**
38:     * Insert a XML Dom Copybook into the Copybook DB
39:     *
40:     * @param copyBookFile Copy Book file Name
41:     * @param splitCopybookOption wether to split a copy book on a redefine
42:     * @param dbIdx Database Index
43:     * @param font font name to use
44:     * @param binFormat binary format to use
45:     * @param systemId System Identifier
46:     * @param log log where any messages should be written
47:     *
48:     * @return record to be inserted
49:     *
50:     * @throws IOException error to be handeled by calling program
51:     * @throws SAXException error to be handeled by calling program
52:     * @throws ParserConfigurationException error to be handeled by calling program
53:     * @throws RecordException general recordeditor exception
54:     */
55:    public abstract ExtendedRecord loadCopyBook(final String copyBookFile,
56:            final int splitCopybookOption, final int dbIdx, final String font,
57:            final int binFormat,
58:            final int systemId,
59:            final AbsSSLogger log) throws IOException,
60:            SAXException, ParserConfigurationException, RecordException;
61:}

Sample Copybook Loader

Following is a simple class to load a Record Layout (copybook) from a Tab delimited file.

   1:/*
   2: * @Author Bruce Martin
   3: * Created on 7/02/2007
   4: *
   5: * Purpose:
   6: * Demonstrate writing a CopybookLoader (ie a class to read
   7: * a record layout or Copybook from> an external file).
   8: */
   9:package net.sf.RecordEditor.examples.CsvLayout;
  10:
  11:import java.io.BufferedReader;
  12:import java.io.FileReader;
  13:import java.io.IOException;
  14:import java.util.HashMap;
  15:import java.util.StringTokenizer;
  16:
  17:import javax.xml.parsers.ParserConfigurationException;
  18:
  19:import org.xml.sax.SAXException;
  20:
  21:import net.sf.RecordEditor.fileLayout.CopybookLoader;
  22:import net.sf.RecordEditor.layoutEd.Record.ExtendedRecord;
  23:import net.sf.RecordEditor.layoutEd.Record.RecordFieldsRec;
  24:import net.sf.RecordEditor.record.Common.RecordException;
  25:import net.sf.RecordEditor.record.types.Type;
  26:import net.sf.RecordEditor.utils.Common;
  27:import net.sf.RecordEditor.utils.log.AbsSSLogger;
  28:
  29:/**
  30: * This class reads a Record Layout (Copybook) stored in a  tab delimited file.
  31: * Fields in the file are<ol>
  32: * <li>Starting Position
  33: * <li>Length
  34: * <li>Number of places after the decimal point
  35: * <li>Field Name
  36: * <li>Field Type (String [or char], num, mainframe_zoned, fuji_zoned)
  37: * </ol>
  38: *
  39: * @author Bruce Martin
  40: *
  41: */
  42:public class CsvLayoutReader implements CopybookLoader {
  43:
  44:    private static HashMap typeConv = new HashMap();
  45:
  46:    static {
  47:        typeConv.put("string", new Integer(Type.ftChar));
  48:        typeConv.put("char", new Integer(Type.ftChar));
  49:        typeConv.put("num", new Integer(Type.ftNumRightJustified));
  50:        typeConv.put("mainframe_zoned", new Integer(Type.ftZonedNumeric));
  51:        typeConv.put("fuji_zoned", new Integer(Type.ftFjZonedNumeric));
  52:    }
  53:
  54:    /**
  55:     * @see net.sf.RecordEditor.fileLayout.CopybookLoader#loadCopyBook(java.lang.String, int, int, java.lang.String, int, int, net.sf.RecordEditor.utils.log.AbsSSLogger)
  56:     */
  57:    public ExtendedRecord loadCopyBook(String copyBookFile,
  58:            int splitCopybookOption, int dbIdx, String font, int binFormat,
  59:            int systemId, AbsSSLogger log) throws IOException, SAXException,
  60:            ParserConfigurationException, RecordException {
  61:
  62:        int rt = Common.rtRecordLayout;
  63:        if (binFormat == FMT_MAINFRAME) {
  64:            rt = Common.rtBinaryRecord;
  65:        }
  66:
  67:        ExtendedRecord rec = ExtendedRecord.getNullRecord(copyBookFile,
  68:                rt,
  69:                font);
  70:
  71:        insertFields(rec, copyBookFile);
  72:
  73:        return rec;
  74:    }
  75:
  76:    /**
  77:     * Add fields to the copybook
  78:     * @param rec copybook
  79:     * @param copyBookFile copybook file
  80:     */
  81:    private void insertFields(ExtendedRecord rec, String copyBookFile) {
  82:        String s, name, typeStr;
  83:        StringTokenizer t;
  84:        RecordFieldsRec field;
  85:        int pos, len, decimal, type;
  86:        int i = 1;
  87:        int inputLine = 1;
  88:        try {
  89:            BufferedReader r = new BufferedReader(new FileReader(copyBookFile));
  90:            while ((s = r.readLine()) != null) {
  91:                if (!s.trim().startsWith("#")) {
  92:                    t = new StringTokenizer(s, "\t");
  93:
  94:                    try {
  95:                        pos  = Integer.parseInt(t.nextToken());
  96:                        len  = Integer.parseInt(t.nextToken());
  97:                        decimal = Integer.parseInt(t.nextToken());
  98:                        name = t.nextToken();
  99:                        typeStr = t.nextToken();
 100:
 101:                        type = Type.ftChar;
 102:                        if (typeStr != null && ! "".equals(typeStr)) {
 103:                            typeStr = typeStr.toLowerCase();
 104:                            if (typeConv.containsKey(typeStr)) {
 105:                                type = ((Integer) typeConv.get(typeStr)).intValue();
 106:                            }
 107:                        }
 108:
 109:                        field = new RecordFieldsRec(pos, len, name, "", type,
 110:                                decimal, 0, "", "", "", i);
 111:                        rec.addRecordField(field);
 112:                        i += 1;
 113:                    } catch (Exception e) {
 114:                        System.out.println("Error Adding line " + inputLine
 115:                                + ": " + e.getMessage());
 116:                        e.printStackTrace();
 117:                    }
 118:                    inputLine += 1;
 119:                }
 120:            }
 121:        } catch (Exception e) {
 122:            System.out.println("Error Adding line " + inputLine
 123:                    + " from file " + copyBookFile
 124:                    + ": " + e.getMessage());
 125:            e.printStackTrace();
 126:        }
 127:    }
 128:}

Adding a Copybook Loader to the RecordEditor

There are 2 steps to defining your Copybook loader to the RecordEditor

  1. First you must add the code you have written to the RecordEditor (as a jar) via the Edit RecordEditor Startup Properties program.

  2. Next you must define your new Class on the Copybook Loaders tag

You should now ne able to import your layouts in to the RecordEditor + Edit your files using your Layouts in the Cobol Editor

Prev Up Next