org.testeditor.fixture.host.screen.Field.java Source code

Java tutorial

Introduction

Here is the source code for org.testeditor.fixture.host.screen.Field.java

Source

/*******************************************************************************
 * Copyright (c) 2012 - 2018 Signal Iduna Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * Signal Iduna Corporation - initial API and implementation
 * akquinet AG
 * itemis AG
 *******************************************************************************/
package org.testeditor.fixture.host.screen;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;

/**
 * The character mainframe ScreenBuffer can contain codes for graphic characters
 * or field attributes. Field attributes define the start of a field and control
 * the characteristics of the field. Because each storage location in the
 * character buffer is mapped to a position on the display screen, the field
 * attribute takes up a character position on the display screen and appears as
 * a blank. The field is defined as the field attribute position plus the
 * character positions up to, but not including, the next field attribute in the
 * character buffer. ScreenBuffer result of x3270 "Readbuffer(Ascii) command in
 * the form: <br>
 * <ul>
 * <li>data: SF(c0=cd) 41 42 43 44 SF(c0=f1) 45 46 47</li>
 * <li>data: SF(c0=f0) 48 49 50 51 SF(c0=f2) 52 53 54</li>
 * <li>...</li>
 * </ul>
 * <b>Caution:</b> the result has to be delivered in formatted structure from
 * mainframe, otherwise we can not parse any field information. See also
 * {@link org.testeditor.fixture.host.HostDriverFixture#printFieldsOnScreen()}
 * 
 * @see org.testeditor.fixture.host.screen.HostTestSite#createHostScreenAsHex()
 * 
 */
public class Field {

    /**
     * Field attribute defines the following field characteristics:
     * <p>
     * Nondisplay or display/intensified display. The selected characteristics
     * apply to the entire field. Nondisplay means that any characters entered
     * from the keyboard are placed in the buffer for possible subsequent
     * transmission to the application program, but they are not displayed.
     * Intensified display means the intensified characters appear on the screen
     * brighter than the nonintensified characters. Some devices cannot
     * intensify characters on the screen and highlight characters in a
     * different manner.
     * <p>
     * The Bit representation of a nondisplay field:
     * <p>
     * <table border="1" >
     * <tr>
     * <th>Binary</td>
     * <th>Hexaddecimal</td>
     * <th>Decimal</td>
     * </tr>
     * <tr>
     * <td>00001100</td>
     * <td>c</td>
     * <td>12</td>
     * </tr>
     * </table>
     * 
     */
    public static final int DISPLAYABLE = 12;

    /**
     * Field attribute defines the following field characteristics:
     * <p>
     * Alphanumeric or numeric. Unprotected alphanumeric fields are fields into
     * which an operator enters data normally, using the shift keys
     * (uppercase/lowercase or numeric/alphabetic) as required. Fields defined
     * as numeric accept all uppercase symbols and numerics from a data entry
     * keyboard. On a typewriter keyboard, numeric has no meaning and all
     * entries are accepted.
     * <p>
     * The Bit representation of a numeric field:
     * <p>
     * <table border="1" >
     * <tr>
     * <th>Binary</td>
     * <th>Hexadecimal</td>
     * <th>Decimal</td>
     * </tr>
     * <tr>
     * <td>00010000</td>
     * <td>10</td>
     * <td>16</td>
     * </tr>
     * </table>
     * 
     */
    public static final int NUMERIC = 16;

    /**
     * Field attribute defines the following field characteristics:
     * <p>
     * Protected or unprotected. A protected field cannot be modified by the
     * operator. The operator can enter data or modify the contents of an
     * unprotected field. Unprotected fields are classified as input fields.
     * <p>
     * The Bit representation of a protected field:
     * <p>
     * <table border="1" >
     * <tr>
     * <th>Binary</td>
     * <th>Hexadecimal</td>
     * <th>Decimal</td>
     * </tr>
     * <tr>
     * <td>00100000</td>
     * <td>20</td>
     * <td>32</td>
     * </tr>
     * </table>
     */
    public static final int PROTECTED = 32;

    /**
     * Number of field attributes
     */
    private int width;

    /**
     * Number of field character attributes
     */
    private int characterWidth;

    /**
     * String Array of field attributes in the form : "(c0=c1), 33, 34, 35"
     */
    private String[] splittedFieldAttributes;

    /**
     * String of the field control characters in the form "c0=c1,42=f5" .
     */
    private String controlCharacters;

    /**
     * String of the field control character value in the form "c1"
     */
    private String controlCharacter;

    /**
     * ArrayList of the field hexadecimal character values in the form "33",
     * "34", "35"
     */
    private ArrayList<String> charactersAsHex;

    /**
     * Parsed field hexadecimal character values as human readable characters in
     * the form "z/OS"
     */
    private String stringRepresentation;

    /**
     * Number of the actual row where the {@link Field} is defined.
     */
    private int rowCount;

    /**
     * Number of the actual {@link Field} in the actual row where the
     * {@link Field} is defined.
     */
    private int fieldCountPerlIne;

    /**
     * Complete row, not parsed e.g. "SF(c0=c1) 31 32 33" "SF(c0=c1) 34 35 36"
     */
    private ArrayList<String> row;

    /**
     * Startpoint of the {@link Field}
     */
    private int startpoint;

    /**
     * Endpoint of the {@link Field}
     */
    private int endpoint;

    /**
     * Startpoint of the field hexadecimal character values
     */
    private int characterStartpoint;

    /**
     * See {@link Field#NUMERIC}
     */
    private boolean numeric;

    /**
     * See {@link Field#DISPLAYABLE}
     */
    private boolean hidden;

    /**
     * See {@link Field#PROTECTED}
     */
    private boolean protectedField;;

    /**
     * @return Control Character
     */
    public String getControlCharacter() {
        return this.controlCharacter;
    }

    /**
     * Represents a String Array with the field attributes in the form "c0=c1",
     * "33", "34", "35".
     * 
     * @param splittedFieldAttributes
     */
    public void setSplittedFieldAttributes(String[] splittedFieldAttributes) {
        this.splittedFieldAttributes = splittedFieldAttributes;
    }

    /**
     * A ControlCharacter is a buffer location which occupies one Byte on a 3270
     * screen. It defines the start of the field and controls the
     * characteristics of a field see IBM Documentation at
     * 3270_Data_Stream_Programmers_Reference @ http://publibz.boulder.ibm.com.
     * 
     * @param splittedFieldAttributes
     *            This is the {@link Field} representation and contains the
     *            control characters called field attribute characters e.g.
     *            SF(c0=c1) and the character attributes as hexadecimal values
     *            like "33 34 35".
     */
    public void setControlCharacters(String[] splittedFieldAttributes) {
        for (String attribute : splittedFieldAttributes) {
            if (attribute.startsWith("(")) {
                this.controlCharacters = attribute;
                break;
            }
        }
    }

    /**
     * Amount of field attributes, the so called control characters and "normal"
     * displayed characters on a 3270 terminal screen. E.g. a Field defined as
     * "SF(c0=c1) 33 34 35 36" has one control character attribute "SF(c0=c1")
     * and four character attributes as hexadecimal values "33 34 35 36" that
     * makes in sum five attributes. So the width of this field would be 5.
     * 
     * @param width
     */
    public void setWidth(int width) {
        this.width = width;
    }

    /**
     * Amount of character attributes, the so called "normal" displayed
     * characters on a 3270 terminal screen. E.g. a Field defined as "SF(c0=c1)
     * 33 34 35 36" has one control character attribute "SF(c0=c1") and four
     * character attributes as hexadecimal values "33 34 35 36" but only the
     * amount of character attributes will be counted here. So the width of this
     * field would be 4.
     * 
     * @param characterWidth
     */
    public void setCharacterWidth(int characterWidth) {
        this.characterWidth = characterWidth;
    }

    /**
     * Field character attributes are the "normal" displayed characters on the
     * display of a 3270 terminal screen. See IBM Documentation at
     * 3270_Data_Stream_Programmers_Reference @ http://publibz.boulder.ibm.com.
     * 
     * @param splittedFieldAttributes
     *            This is the {@link Field} representation and contains the
     *            control characters called field attribute characters e.g.
     *            SF(c0=c1) and the character attributes as hexadecimal values
     *            like "33 34 35".
     */
    public void setCharacters(String[] splittedFieldAttributes) {
        ArrayList<String> charactersAsHex = new ArrayList<String>();

        for (String attribute : splittedFieldAttributes) {
            if (!attribute.startsWith("(")) {
                charactersAsHex.add(attribute);
            }
        }
        this.charactersAsHex = charactersAsHex;
    }

    public ArrayList<String> getCharactersAsHex() {
        return this.charactersAsHex;
    }

    /**
     * The {@link ArrayList} of Hex values {"41", "42", "43", "44", "45", "46"}
     * parsed into a String representation --> "ABCDEF"
     * 
     * @param charactersAsHex
     *            List of characters in Hex format {"41", "42", "43", "44",
     *            "45", "46"}
     */
    public void setStringRepresentation(ArrayList<String> charactersAsHex) {
        StringBuffer buffer = new StringBuffer();
        for (String string : charactersAsHex) {
            buffer.append(string);
        }
        char[] characters = buffer.toString().toCharArray();
        byte[] bytes;
        try {
            bytes = Hex.decodeHex(characters);
            this.stringRepresentation = new String(bytes, "UTF-8");
        } catch (DecoderException | UnsupportedEncodingException e) {
            throw new RuntimeException(e.getMessage());
        }

    }

    public void setColumnNumber(int rowCount) {
        this.rowCount = rowCount;

    }

    public void setFieldCountPerLine(int fieldCount) {
        this.fieldCountPerlIne = fieldCount;

    }

    /**
     * Sets {@link Field} attributes like startpoint, width, endpoint,
     * characterWidth, characterStartpoint, row
     * 
     * @param row
     *            ArrayList of all Fields in one row in the form "(c0=cd) 30 31
     *            32 33" , "(c0=c1) 34 35 36 37"
     * @param fieldCount
     *            The number of the actual {@link Field} to set the field
     *            attributes in actual row.
     */
    public void setFieldAttributes(ArrayList<String> row, int fieldCount) {
        ArrayList<Integer> allLengthValuesOfRow = new ArrayList<Integer>();
        ArrayList<String> allFieldValuesInRow = new ArrayList<String>();

        int begin = fieldCount - 1;
        int startpoint = 0;
        int lengthToAdd = 0;
        int fieldWidth = 0;

        for (String field : row) {
            String[] splittedValues = field.split(" ");
            fieldWidth = splittedValues.length;
            allFieldValuesInRow.add(field);
            allLengthValuesOfRow.add(new Integer(fieldWidth));
        }

        for (int i = 0; i < begin; i++) {
            lengthToAdd = lengthToAdd + allLengthValuesOfRow.get(i);
        }
        startpoint = lengthToAdd;
        this.startpoint = startpoint;
        this.width = allLengthValuesOfRow.get(begin);
        this.endpoint = startpoint + this.width - 1;
        this.characterWidth = this.width - 1;
        this.characterStartpoint = this.startpoint + 1;
        this.row = row;
    }

    public int getFieldCountPerline() {
        return this.fieldCountPerlIne;
    }

    public int getRowCount() {
        return this.rowCount;
    }

    public int getCharacterWidth() {
        return this.characterWidth;
    }

    public int getCharacterStartpoint() {
        return this.characterStartpoint;
    }

    public int getEndpoint() {
        return this.endpoint;
    }

    public boolean IsNumeric() {
        return this.numeric;
    }

    public boolean isProtected() {
        return this.protectedField;
    }

    public boolean isHidden() {
        return this.hidden;
    }

    public String getStringReperentation() {
        return this.stringRepresentation;
    }

    public void setControlCharacter(String line, int fieldNr) {
        this.controlCharacter = createControlCharacter(line, fieldNr);
    }

    /**
     * More information can be found under:
     * 
     * <pre>
     * File : x3270\include\3270ds.h
     * Sources : <a href=
    * "https://sourceforge.net/p/x3270/code/ci/master/tree/">https://sourceforge.net/p/x3270/code/ci/master/tree/</a>
     * 
     * Here are the bit definitions from the source  :
     * 
     * #define FA_PRINTABLE     0xc0    these make the character "printable" 
     * #define FA_PROTECT       0x20    unprotected (0) / protected (1) 
     * #define FA_NUMERIC       0x10    alphanumeric (0) /numeric (1)
     * #define FA_INTENSITY     0x0c    display/selector pen detectable:
     * #define FA_INT_NORM_NSEL 0x00    00 normal, non-detect 
     * #define FA_INT_NORM_SEL  0x04    01 normal, detectable 
     * #define FA_INT_HIGH_SEL  0x08    10 intensified, detectable 
     * #define FA_INT_ZERO_NSEL 0x0c    11 nondisplay, non-detect 
     * #define FA_RESERVED      0x02    must be 0 
     * #define FA_MODIFY        0x01    modified (1) 
     * 
     * This translates as follows:
     *      +--------------------+----------+---------+----------------------+---------+--------+
     * Bits |    7         6     |    5     |    4    |     3          2     |    1    |   0    |
     *      +--------------------+----------+---------+----------------------+---------+--------+
     *      |       Ignore       | Protect  | Numeric |     Display Mode     | Ignore  |Modified|
     *      +--------------------+----------+---------+----------------------+---------+--------+
     * </pre>
     * 
     * @param controlCharacter
     *            The so called field attribute defines the start of a field and
     *            the characteristics of the field.
     *            <p>
     *            Field attribute defines the following field characteristics:
     *            <ul>
     *            <li>Protected or unprotected. A protected field cannot be
     *            modified by the operator. The operator can enter data or
     *            modify the contents of an unprotected field. Unprotected
     *            fields are classified as input fields.
     *            <p>
     *            The Bit representation of a protected field:
     *            <table border="1" >
     *            <tr>
     *            <th>Binary</td>
     *            <th>Hexadecimal</td>
     *            <th>Decimal</td>
     *            </tr>
     *            <tr>
     *            <td>00100000</td>
     *            <td>20</td>
     *            <td>32</td>
     *            </tr>
     *            </table>
     *            </li>
     *            <li>Alphanumeric or numeric. Unprotected alphanumeric fields
     *            are fields into which an operator enters data normally, using
     *            the shift keys (uppercase/lowercase or numeric/alphabetic) as
     *            required. Fields defined as numeric accept all uppercase
     *            symbols and numerics from a data entry keyboard. On a
     *            typewriter keyboard, numeric has no meaning and all entries
     *            are accepted.
     *            <p>
     *            The Bit representation of a numeric field:
     *            <table border="1" >
     *            <tr>
     *            <th>Binary</td>
     *            <th>Hexadecimal</td>
     *            <th>Decimal</td>
     *            </tr>
     *            <tr>
     *            <td>00010000</td>
     *            <td>10</td>
     *            <td>16</td>
     *            </tr>
     *            </table>
     *            </li>
     *            <li>Nondisplay or display/intensified display. The selected
     *            characteristics apply to the entire field. Nondisplay means
     *            that any characters entered from the keyboard are placed in
     *            the buffer for possible subsequent transmission to the
     *            application program, but they are not displayed. Intensified
     *            display means the intensified characters appear on the screen
     *            brighter than the nonintensified characters. Some devices
     *            cannot intensify characters on the screen and highlight
     *            characters in a different manner.
     *            <p>
     *            The Bit representation of a nondisplay field:
     *            <table border="1" >
     *            <tr>
     *            <th>Binary</td>
     *            <th>Hexaddecimal</td>
     *            <th>Decimal</td>
     *            </tr>
     *            <tr>
     *            <td>00001100</td>
     *            <td>c</td>
     *            <td>12</td>
     *            </tr>
     *            </table>
     *            </li>
     *            </ul>
     * 
     * @param hexValueForAttribute
     *            the hexadecimal representation of a {@link Field} attribute
     *            valie
     * @return true if the hex value for the attribute correlates with the
     *         control character, false otherwise. If a control character
     *         correlates bitwise.
     * 
     */
    public boolean isAttribute(String controlCharacter, int hexValueForAttribute) {
        boolean isAttribute = false;
        int intValue = Long.decode("0x" + controlCharacter).intValue();
        int attributeInt = intValue & hexValueForAttribute;
        if (attributeInt == hexValueForAttribute) {
            isAttribute = true;
        }
        return isAttribute;
    }

    public void setHidden(boolean hidden) {
        this.hidden = hidden;
    }

    public void setNumeric(boolean numeric) {
        this.numeric = numeric;
    }

    public void setProtected(boolean protectedField) {
        this.protectedField = protectedField;
    }

    /**
     * Extracts the {@link Field} Control Characters within a row.
     * 
     * @param line
     *            The complete raw row String.
     * @param fieldNr
     *            The number of the specified Field on one row.
     * @return the extracted Control Character in the form "cd".
     */
    private String createControlCharacter(String line, int fieldNr) {
        String result = null;
        String controlCharacter = null;
        Matcher m = Pattern.compile("\\((.*?)\\)").matcher(line);
        int counter = 1;
        while (m.find()) {
            String group = m.group(1);
            if (counter++ == fieldNr) {
                Matcher m2 = Pattern.compile("c0=.{2}").matcher(group);
                while (m2.find()) {
                    controlCharacter = m2.group(0);

                    String[] splittedHexValues = controlCharacter.split("=");
                    result = splittedHexValues[1];
                }
            }
        }
        return result;
    }

}