/** * If the outbound level is BINARY, convert the string field to binary, then pad to the left with * the appropriate number of zero bits to reach a number of bits specified by the bitLength * attribute of the TDT definition file. */ private void binaryPadding(Map<String, String> extraparams, Field tdtfield) { String fieldname = tdtfield.getName(); int reqbitlength = tdtfield.getBitLength(); String value; String binaryValue = fieldToBinary(tdtfield, extraparams); if (binaryValue.length() < reqbitlength) { int extraBitLength = reqbitlength - binaryValue.length(); StringBuilder zeroPaddedBinaryValue = new StringBuilder(""); for (int i = 0; i < extraBitLength; i++) { zeroPaddedBinaryValue.append("0"); } zeroPaddedBinaryValue.append(binaryValue); value = zeroPaddedBinaryValue.toString(); } else { if (binaryValue.length() > reqbitlength) throw new TDTException( "Binary value [" + binaryValue + "] for field " + fieldname + " exceeds maximum allowed " + reqbitlength + " bits. Decimal value was " + extraparams.get(fieldname)); value = binaryValue; } extraparams.put(fieldname, value); }
/** * Converts an alphanumeric string input into a binary string, using 6-bit compaction of each * ASCII byte */ private String alphanumsix2bin(String alphanumsix) { String binary; StringBuilder buffer = new StringBuilder(""); int len = alphanumsix.length(); byte[] bytes = alphanumsix.getBytes(); for (int i = 0; i < len; i++) { buffer.append(padBinary(dec2bin(Integer.toString(bytes[i] % 64)), 8).substring(2, 8)); } binary = buffer.toString(); return binary; }
/** * Converts a binary string input into an ASCII string output, assuming that 7-bit compaction was * used */ private String bin2asciiseven(String binary) { String asciiseven; StringBuilder buffer = new StringBuilder(""); int len = binary.length(); for (int i = 0; i < len; i += 7) { int j = Integer.parseInt(bin2dec(padBinary(binary.substring(i, i + 7), 8))); buffer.append((char) j); } asciiseven = buffer.toString(); return asciiseven; }
/** * Converts an ASCII string input into a binary string, using 7-bit compaction of each ASCII byte */ private String asciiseven2bin(String asciiseven) { String binary; StringBuilder buffer = new StringBuilder(""); int len = asciiseven.length(); byte[] bytes = asciiseven.getBytes(); for (int i = 0; i < len; i++) { buffer.append(padBinary(dec2bin(Integer.toString(bytes[i] % 128)), 8).substring(1, 8)); } binary = buffer.toString(); return binary; }
/** Converts a byte string input into a binary string, using 8-bits per character byte */ private String bin2bytestring(String binary) { String bytestring; StringBuilder buffer = new StringBuilder(""); int len = binary.length(); for (int i = 0; i < len; i += 8) { int j = Integer.parseInt(bin2dec(padBinary(binary.substring(i, i + 8), 8))); buffer.append((char) j); } bytestring = buffer.toString(); return bytestring; }
/** Converts a binary string input into a byte string, using 8-bits per character byte */ private String bytestring2bin(String bytestring) { String binary; StringBuilder buffer = new StringBuilder(""); int len = bytestring.length(); byte[] bytes = bytestring.getBytes(); for (int i = 0; i < len; i++) { buffer.append(padBinary(dec2bin(Integer.toString(bytes[i])), 8)); } binary = buffer.toString(); return binary; }
/** * Converts a binary string input into a character string output, assuming that 5-bit compaction * was used */ private String bin2uppercasefive(String binary) { String uppercasefive; StringBuilder buffer = new StringBuilder(""); int len = binary.length(); for (int i = 0; i < len; i += 5) { int j = Integer.parseInt(bin2dec(padBinary(binary.substring(i, i + 5), 8))); buffer.append((char) (j + 64)); } uppercasefive = buffer.toString(); return uppercasefive; }
/** * Converts an upper case character string input into a binary string, using 5-bit compaction of * each ASCII byte */ private String uppercasefive2bin(String uppercasefive) { String binary; StringBuilder buffer = new StringBuilder(""); int len = uppercasefive.length(); byte[] bytes = uppercasefive.getBytes(); for (int i = 0; i < len; i++) { buffer.append(padBinary(dec2bin(Integer.toString(bytes[i] % 32)), 8).substring(3, 8)); } binary = buffer.toString(); return binary; }
/** * Pads a binary value supplied as a string first parameter to the left with leading zeros in * order to reach a required number of bits, as expressed by the second parameter, reqlen. Returns * a string value corresponding to the binary value left padded to the required number of bits. */ private String padBinary(String binary, int reqlen) { String rv; int l = binary.length(); int pad = (reqlen - (l % reqlen)) % reqlen; StringBuilder buffer = new StringBuilder(""); for (int i = 0; i < pad; i++) { buffer.append("0"); } buffer.append(binary); rv = buffer.toString(); return rv; }
/** * Returns a string built using a particular grammar. Single-quotes strings are counted as literal * strings, whereas all other strings appearing in the grammar require substitution with the * corresponding value from the extraparams hashmap. */ private String buildGrammar(String grammar, Map<String, String> extraparams) { StringBuilder outboundstring = new StringBuilder(); String[] fields = Pattern.compile("\\s+").split(grammar); for (int i = 0; i < fields.length; i++) { if (fields[i].substring(0, 1).equals("'")) { outboundstring.append(fields[i].substring(1, fields[i].length() - 1)); } else { outboundstring.append(extraparams.get(fields[i])); } } return outboundstring.toString(); }
/** * Converts a binary string input into a character string output, assuming that 6-bit compaction * was used */ private String bin2alphanumsix(String binary) { String alphanumsix; StringBuilder buffer = new StringBuilder(""); int len = binary.length(); for (int i = 0; i < len; i += 6) { int j = Integer.parseInt(bin2dec(padBinary(binary.substring(i, i + 6), 8))); if (j < 32) { j += 64; } buffer.append((char) j); } alphanumsix = buffer.toString(); return alphanumsix; }
/** pad a value according the field definition. */ private void padField(Map<String, String> extraparams, Field field) { String name = field.getName(); String value = extraparams.get(name); PadDirectionList padDir = field.getPadDir(); int requiredLength = field.getLength(); // assert value != null; if (value == null) return; String padCharString = field.getPadChar(); // if no pad char specified, don't attempt padding if (padCharString == null) return; assert padCharString.length() > 0; char padChar = padCharString.charAt(0); StringBuilder buf = new StringBuilder(requiredLength); if (padDir == PadDirectionList.LEFT) { for (int i = 0; i < requiredLength - value.length(); i++) buf.append(padChar); buf.append(value); } else if (padDir == PadDirectionList.RIGHT) { buf.append(value); for (int i = 0; i < requiredLength - value.length(); i++) buf.append(padChar); } assert buf.length() == requiredLength; if (requiredLength != value.length()) { // System.out.println(" updated " + name + " to '" + buf + "'"); extraparams.put(name, buf.toString()); } /* else { StringBuilder mybuf = new StringBuilder(); for (int i = 0; i < value.length(); i++) { if (i > 0) mybuf.append(','); mybuf.append('\''); mybuf.append(value.charAt(i)); mybuf.append('\''); } System.out.println(" field " + name + " not padded as " + mybuf.toString() + " is already " + requiredLength + " characters long"); } */ }
/** * Adds additional entries to the extraparams hashmap by processing various rules defined in the * TDT definition files. Typically used for string processing functions, lookup in tables, * calculation of check digits etc. */ private void processRules(Map<String, String> extraparams, Rule tdtrule) { String tdtfunction = tdtrule.getFunction(); int openbracket = tdtfunction.indexOf("("); assert openbracket != -1; String params = tdtfunction.substring(openbracket + 1, tdtfunction.length() - 1); String rulename = tdtfunction.substring(0, openbracket); String[] parameter = params.split(","); String newfieldname = tdtrule.getNewFieldName(); // System.out.println(tdtfunction + " " + parameter[0] + " " + extraparams.get(parameter[0])); /** * Stores in the hashmap extraparams the value obtained from a lookup in a specified XML table. * * <p>The first parameter is the given value already known. This is denoted as $1 in the * corresponding XPath expression * * <p>The second parameter is the string filename of the table which must be present in the * auxiliary subdirectory * * <p>The third parameter is the column in which the supplied input value should be sought * * <p>The fourth parameter is the column whose value should be read for the corresponding row, * in order to obtain the result of the lookup. * * <p>The rule in the definition file may contain an XPath expression and a URL where the table * may be obtained. */ if (rulename.equals("TABLELOOKUP")) { // parameter[0] is given value // parameter[1] is table // parameter[2] is input column supplied // parameter[3] is output column required assert parameter.length == 4 : "incorrect number of parameters to tablelookup " + params; if (parameter[1].equals("tdt64bitcpi")) { String s = extraparams.get(parameter[0]); assert s != null : tdtfunction + " when " + parameter[0] + " is null"; String t = gs1cpi.get(s); assert t != null : "gs1cpi[" + s + "] is null"; assert newfieldname != null; extraparams.put(newfieldname, t); // extraparams.put(newfieldname, gs1cpi.get(extraparams.get(parameter[0]))); } else { // JPB! the following is untested String tdtxpath = tdtrule.getTableXPath(); String tdttableurl = tdtrule.getTableURL(); String tdtxpathsub = tdtxpath.replaceAll("\\$1", extraparams.get(parameter[0])); extraparams.put(newfieldname, xpathlookup("ManagerTranslation.xml", tdtxpathsub)); } } /** * Stores the length of the specified string under the new fieldname specified by the * corresponding rule of the definition file. */ if (rulename.equals("LENGTH")) { assert extraparams.get(parameter[0]) != null : tdtfunction + " when " + parameter[0] + " is null"; if (extraparams.get(parameter[0]) != null) { extraparams.put(newfieldname, Integer.toString(extraparams.get(parameter[0]).length())); } } /** * Stores a GS1 check digit in the extraparams hashmap, keyed under the new fieldname specified * by the corresponding rule of the definition file. */ if (rulename.equals("GS1CHECKSUM")) { assert extraparams.get(parameter[0]) != null : tdtfunction + " when " + parameter[0] + " is null"; if (extraparams.get(parameter[0]) != null) { extraparams.put(newfieldname, gs1checksum(extraparams.get(parameter[0]))); } } /** * Obtains a substring of the string provided as the first parameter. If only a single second * parameter is specified, then this is considered as the start index and all characters from * the start index onwards are stored in the extraparams hashmap under the key named * 'newfieldname' in the corresponding rule of the definition file. If a second and third * parameter are specified, then the second parameter is the start index and the third is the * length of characters required. A substring consisting characters from the start index up to * the required length of characters is stored in the extraparams hashmap, keyed under the new * fieldname specified by the corresponding rule of the defintion file. */ if (rulename.equals("SUBSTR")) { assert extraparams.get(parameter[0]) != null : tdtfunction + " when " + parameter[0] + " is null"; if (parameter.length == 2) { if (extraparams.get(parameter[0]) != null) { int start = getIntValue(parameter[1], extraparams); if (start >= 0) { extraparams.put(newfieldname, extraparams.get(parameter[0]).substring(start)); } } } if (parameter.length == 3) { // need to check that this variation is correct - c.f. Perl substr assert extraparams.get(parameter[0]) != null : tdtfunction + " when " + parameter[0] + " is null"; if (extraparams.get(parameter[0]) != null) { int start = getIntValue(parameter[1], extraparams); int end = getIntValue(parameter[2], extraparams); if ((start >= 0) && (end >= 0)) { extraparams.put( newfieldname, extraparams.get(parameter[0]).substring(start, start + end)); } } } } /** * Concatenates specified string parameters together. Literal values must be enclosed within * single or double quotes or consist of unquoted digits. Other unquoted strings are considered * as fieldnames and the corresponding value from the extraparams hashmap are inserted. The * result of the concatenation (and substitution) of the strings is stored as a new entry in the * extraparams hashmap, keyed under the new fieldname specified by the rule. */ if (rulename.equals("CONCAT")) { StringBuilder buffer = new StringBuilder(); for (int p1 = 0; p1 < parameter.length; p1++) { Matcher matcher = Pattern.compile("\"(.*?)\"|'(.*?)'|[0-9]").matcher(parameter[p1]); if (matcher.matches()) { buffer.append(parameter[p1]); } else { assert extraparams.get(parameter[p1]) != null : tdtfunction + " when " + parameter[p1] + " is null"; if (extraparams.get(parameter[p1]) != null) { buffer.append(extraparams.get(parameter[p1])); } } } extraparams.put(newfieldname, buffer.toString()); } }