示例#1
1
  /**
   * 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);
  }
示例#2
0
 public static String convertStreamToString(InputStream is) throws Exception {
   BufferedReader reader = new BufferedReader(new InputStreamReader(is));
   StringBuilder sb = new StringBuilder();
   String line = null;
   while ((line = reader.readLine()) != null) {
     sb.append(line + "\n");
   }
   is.close();
   return sb.toString();
 }
示例#3
0
 /**
  * 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;
 }
示例#4
0
 /**
  * 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;
 }
示例#5
0
 /** 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;
 }
示例#6
0
 /**
  * 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;
 }
示例#7
0
 /**
  * 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;
 }
示例#8
0
 /** 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;
 }
 /**
  * takes a parameterised query string and a param name - param value map and substitutes
  * parameters for values
  *
  * @param parameterisedQuery the query
  * @param paramMap the map containing parameters + values
  * @return a query string
  */
 public static String substituteQueryParameters(
     String parameterisedQuery, Map<String, String> paramMap) {
   StringBuilder sb = new StringBuilder(parameterisedQuery);
   String completeQuery = sb.toString();
   for (Map.Entry<String, String> entry : paramMap.entrySet()) {
     String parameter = "%" + entry.getKey() + "%";
     String value = entry.getValue();
     completeQuery = completeQuery.replace(parameter, value);
   }
   return completeQuery;
 }
示例#10
0
 /**
  * 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;
 }
示例#11
0
 /**
  * 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;
 }
示例#12
0
  /**
   * 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();
  }
 @Override
 public String toString() {
   StringBuilder output =
       new StringBuilder("DialogInfoMessagePart for ")
           .append(entity)
           .append(": state='")
           .append(state)
           .append("'\n");
   for (DialogInfo di : this.dialogsList) {
     output.append(di.toString());
   }
   return output.toString();
 }
示例#14
0
 /**
  * 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;
 }
示例#15
0
  private Document GET(String callName, String callPrefix, AlchemyAPI_Params params)
      throws IOException, SAXException, ParserConfigurationException, XPathExpressionException {
    StringBuilder uri = new StringBuilder();
    uri.append(_requestUri)
        .append(callPrefix)
        .append('/')
        .append(callName)
        .append('?')
        .append("apikey=")
        .append(this._apiKey);
    uri.append(params.getParameterString());

    URL url = new URL(uri.toString());
    HttpURLConnection handle = (HttpURLConnection) url.openConnection();
    handle.setDoOutput(true);

    return doRequest(handle, params.getOutputMode());
  }
示例#16
0
  private Document POST(String callName, String callPrefix, AlchemyAPI_Params params)
      throws IOException, SAXException, ParserConfigurationException, XPathExpressionException {
    URL url = new URL(_requestUri + callPrefix + "/" + callName);

    HttpURLConnection handle = (HttpURLConnection) url.openConnection();
    handle.setDoOutput(true);

    StringBuilder data = new StringBuilder();

    data.append("apikey=").append(this._apiKey);
    data.append(params.getParameterString());

    handle.addRequestProperty("Content-Length", Integer.toString(data.length()));

    DataOutputStream ostream = new DataOutputStream(handle.getOutputStream());
    ostream.write(data.toString().getBytes());
    ostream.close();

    return doRequest(handle, params.getOutputMode());
  }
示例#17
0
 /**
  * Yet another stream 2 string function.
  *
  * @param is the stream
  * @param encoding the encoding of the bytes in the stream
  * @return the string.
  */
 public static String getStringFromInputStream(InputStream is, String encoding) {
   String line = null;
   if (is == null) {
     return "";
   }
   BufferedReader in = null;
   try {
     in = new BufferedReader(new InputStreamReader(is, encoding));
   } catch (UnsupportedEncodingException e) {
     throw new IllegalArgumentException("Unsupported encoding: " + encoding, e);
   }
   StringBuilder sb = new StringBuilder();
   try {
     while ((line = in.readLine()) != null) {
       sb.append(line);
     }
   } catch (IOException e) {
     throw new IllegalArgumentException("Unable to read from stream", e);
   }
   return sb.toString();
 }
示例#18
0
    public Credentials authenticate() throws Exception {
      HttpURLConnection urlConnection =
          new ConnBuilder(authUrl)
              .addHeader(HttpHeaders.CONTENT_TYPE_HEADER, "application/json")
              .addHeader(HttpHeaders.ACCEPT_HEADER, "application/xml")
              .getConnection();

      StringBuilder jsonBuilder = new StringBuilder();
      jsonBuilder
          .append("{\"auth\": {\"tenantName\": \"")
          .append(tenant)
          .append("\", \"passwordCredentials\": {\"username\": \"")
          .append(username)
          .append("\", \"password\": \"")
          .append(password)
          .append("\"}}}");

      HttpResponse response =
          Utils.doOperation(urlConnection, jsonBuilder.toString().getBytes(), true);

      if (response.isSuccessCode()) {

        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder();
        Document doc = builder.parse(new ByteArrayInputStream(response.payload));

        String authToken = (String) tokenIdExpression.evaluate(doc, XPathConstants.STRING);
        String storageUrl = (String) publicUrlExpression.evaluate(doc, XPathConstants.STRING);

        log.trace("Authentication successful");

        return new Credentials(authToken, storageUrl);
      } else {
        throw new IllegalStateException(
            "Error authenticating to the service. Please check your credentials. Code = "
                + response.code);
      }
    }
示例#19
0
  /** 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");
    }
    */
  }
 /**
  * Returns the HTTP encoded string required for web service authentication.
  *
  * <p>Order of authentication methods: token then username/password, if token not initialised or
  * null if both methods not initialised.
  *
  * @return String containing HTTP encoded string or null.
  * @throws UnsupportedEncodingException
  */
 public static String getAuth() throws UnsupportedEncodingException {
   StringBuilder data = new StringBuilder();
   if (MoodleCallRestWebService.getToken() != null) {
     data.append(URLEncoder.encode("wstoken", "UTF-8"))
         .append("=")
         .append(URLEncoder.encode(MoodleCallRestWebService.getToken(), "UTF-8"));
   } else {
     if (MoodleCallRestWebService.getUsername() != null
         && MoodleCallRestWebService.getPassword() != null) {
       data.append(URLEncoder.encode("wsusername", "UTF-8"))
           .append("=")
           .append(URLEncoder.encode(MoodleCallRestWebService.getUsername(), "UTF-8"));
       data.append("&"); // Fix by César Martínez
       data.append(URLEncoder.encode("wspassword", "UTF-8"))
           .append("=")
           .append(URLEncoder.encode(MoodleCallRestWebService.getPassword(), "UTF-8"));
     } else return null;
   }
   return data.toString();
 }
  private synchronized void parse() {
    try {
      // XPath does not handle default XML namespaces very well.
      // Although we could set up a NamespaceContext to map the
      // urn:ietf:params:xml:ns:dialog-info namespace to a prefix
      // that we could use in our subsequent 'xpath.evaluate()' calls
      // this leads to ugly code.  Because the dialog info XML
      // body only uses the default namespace, we are taking a
      // shortcut here and remove the default namespace from to
      // body.

      XPath xpath = XPathFactory.newInstance().newXPath();
      String namespaceLessContent = this.getContent().replace("xmlns", "dummy");
      ByteArrayInputStream is = new ByteArrayInputStream(namespaceLessContent.getBytes());
      InputSource source = new InputSource(is);

      // get entity info
      this.entity = xpath.evaluate("/dialog-info/@entity", source);
      is.reset();

      // get state info
      this.state = xpath.evaluate("/dialog-info/@state", source);
      is.reset();

      // get dialog states
      String countAsString = xpath.evaluate("count(/dialog-info/dialog)", source);
      is.reset();
      int dialogCount = Integer.parseInt(countAsString);

      // process each dialog
      for (int index = 0; index < dialogCount; index++) {
        StringBuilder dialogIdEvalString =
            new StringBuilder("/dialog-info/dialog[").append(index + 1).append("]/@id");
        StringBuilder dialogStateEvalString =
            new StringBuilder("/dialog-info/dialog[").append(index + 1).append("]/state");
        StringBuilder localDisplayNameEvalString =
            new StringBuilder("/dialog-info/dialog[")
                .append(index + 1)
                .append("]/local/identity/@display");
        StringBuilder localIdentityEvalString =
            new StringBuilder("/dialog-info/dialog[").append(index + 1).append("]/local/identity");
        StringBuilder localTargetUriEvalString =
            new StringBuilder("/dialog-info/dialog[")
                .append(index + 1)
                .append("]/local/target/@uri");
        StringBuilder remoteDisplayNameEvalString =
            new StringBuilder("/dialog-info/dialog[")
                .append(index + 1)
                .append("]/remote/identity/@display");
        StringBuilder remoteIdentityEvalString =
            new StringBuilder("/dialog-info/dialog[").append(index + 1).append("]/remote/identity");
        StringBuilder remoteTargetUriEvalString =
            new StringBuilder("/dialog-info/dialog[")
                .append(index + 1)
                .append("]/remote/target/@uri");

        String id = xpath.evaluate(dialogIdEvalString.toString(), source);
        is.reset();
        String state = xpath.evaluate(dialogStateEvalString.toString(), source);
        is.reset();
        String localDisplayName = xpath.evaluate(localDisplayNameEvalString.toString(), source);
        is.reset();
        String localIdentity = xpath.evaluate(localIdentityEvalString.toString(), source);
        is.reset();
        String localTargetUri = xpath.evaluate(localTargetUriEvalString.toString(), source);
        is.reset();
        String remoteDisplayName = xpath.evaluate(remoteDisplayNameEvalString.toString(), source);
        is.reset();
        String remoteIdentity = xpath.evaluate(remoteIdentityEvalString.toString(), source);
        is.reset();
        String remoteTargetUri = xpath.evaluate(remoteTargetUriEvalString.toString(), source);
        is.reset();

        EndpointInfo localInfo = new EndpointInfo(localDisplayName, localIdentity, localTargetUri);
        EndpointInfo remoteInfo =
            new EndpointInfo(remoteDisplayName, remoteIdentity, remoteTargetUri);
        DialogInfo dialogInfo = new DialogInfo(id, state, localInfo, remoteInfo);
        dialogsList.add(dialogInfo);
      }
    } catch (Exception ex) {
      logger.error("DialogInfoMessagePart::parse caught " + ex.getMessage());
    }
  }
 /**
  * This calls the external Moodle web service.
  *
  * <p>params String containing the parameters of the call.<br>
  * elements NodeList containing name/value pairs of returned XML data.
  *
  * @param params String
  * @return elements NodeList
  * @throws MoodleRestException
  */
 public static NodeList call(String params) throws MoodleRestException {
   NodeList elements = null;
   try {
     URL getUrl = new URL(url);
     HttpURLConnection connection = (HttpURLConnection) getUrl.openConnection();
     connection.setRequestMethod("POST");
     connection.setRequestProperty("Accept", "application/xml");
     connection.setDoOutput(true);
     OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
     writer.write(params);
     writer.flush();
     writer.close();
     // Used for testing
     StringBuilder buffer = new StringBuilder();
     BufferedReader reader =
         new BufferedReader(new InputStreamReader(connection.getInputStream()));
     String line = reader.readLine();
     buffer.append(line).append('\n');
     // FindPath fp=new FindPath();
     InputStream resource =
         ClassLoader.getSystemClassLoader()
             .getResourceAsStream("net/beaconhillcott/moodlerest/EntityInjection.xml");
     BufferedReader entities = new BufferedReader(new InputStreamReader(/*fp.*/ resource));
     String entitiesLine = null;
     while ((entitiesLine = entities.readLine()) != null) {
       // System.out.println(entitiesLine);
       buffer.append(entitiesLine).append('\n');
     }
     entities.close();
     boolean error = false;
     while ((line = reader.readLine()) != null) {
       // System.out.println(line);
       if (error)
         throw new MoodleRestException(
             line.substring(line.indexOf('>') + 1, line.indexOf('<', line.indexOf('>') + 1)));
       if (line.contains("<EXCEPTION")) error = true;
       buffer.append(line).append('\n');
     }
     reader.close();
     if (debug) {
       System.out.println(buffer.toString());
     }
     XPath xpath = XPathFactory.newInstance().newXPath();
     // InputSource source=new InputSource(connection.getInputStream());
     InputSource source = new InputSource(new ByteArrayInputStream(buffer.toString().getBytes()));
     elements = (NodeList) xpath.evaluate("//VALUE", source, XPathConstants.NODESET);
     // Used for testing
     if (debug) {
       for (int i = 0; i < elements.getLength(); i++) {
         String parent =
             elements
                 .item(i)
                 .getParentNode()
                 .getParentNode()
                 .getParentNode()
                 .getParentNode()
                 .getNodeName();
         if (parent.equals("KEY"))
           parent =
               elements
                   .item(i)
                   .getParentNode()
                   .getParentNode()
                   .getParentNode()
                   .getParentNode()
                   .getAttributes()
                   .getNamedItem("name")
                   .getNodeValue();
         String content = elements.item(i).getTextContent();
         String nodeName =
             elements.item(i).getParentNode().getAttributes().getNamedItem("name").getNodeValue();
         System.out.println("parent=" + parent + " nodeName=" + nodeName + " content=" + content);
       }
     }
     connection.disconnect();
   } catch (XPathExpressionException ex) {
     Logger.getLogger(MoodleCallRestWebService.class.getName()).log(Level.SEVERE, null, ex);
   } catch (IOException ex) {
     Logger.getLogger(MoodleCallRestWebService.class.getName()).log(Level.SEVERE, null, ex);
   }
   return elements;
 }
示例#23
0
  /**
   * 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());
    }
  }