Beispiel #1
0
 /**
  * find a level by its type in a scheme. This involves iterating through the list of levels. The
  * main reason for doing it this way is to avoid being dependent on the order in which the levels
  * are coded in the xml, which is not explicitly constrained.
  */
 private Level findLevel(Scheme scheme, LevelTypeList levelType) {
   Level level = null;
   for (Enumeration e = scheme.enumerateLevel(); e.hasMoreElements(); ) {
     Level lev = (Level) e.nextElement();
     if (lev.getType() == levelType) {
       level = lev;
       break;
     }
   }
   if (level == null) throw new Error("Couldn't find type " + levelType + " in scheme " + scheme);
   return level;
 }
Beispiel #2
0
  /**
   * find a option by its type in a scheme. This involves iterating through the list of options. The
   * main reason for doing it this way is to avoid being dependent on the order in which the options
   * are coded in the xml, which is not explicitly constrained.
   */
  private Option findOption(Level level, String optionKey) {
    Option option = null;

    for (Enumeration e = level.enumerateOption(); e.hasMoreElements(); ) {
      Option opt = (Option) e.nextElement();
      if (opt.getOptionKey().equals(optionKey)) {
        option = opt;
        break;
      }
    }
    if (option == null)
      throw new Error("Couldn't find option for " + optionKey + " in level " + level);

    return option;
  }
Beispiel #3
0
  /**
   * TDTEngine - constructor for a new Tag Data Translation engine
   *
   * @param confdir the string value of the path to a configuration directory consisting of two
   *     subdirectories, <code>schemes</code> and <code>auxiliary</code>.
   *     <p>When the class TDTEngine is constructed, the path to a local directory must be
   *     specified, by passing it as a single string parameter to the constructor method (without
   *     any trailing slash or file separator). e.g. <code>
   *     <pre>TDTEngine engine = new TDTEngine("/opt/TDT");</pre></code>
   *     <p>The specified directory must contain two subdirectories named auxiliary and schemes. The
   *     Tag Data Translation definition files for the various coding schemes should be located
   *     inside the subdirectory called <code>schemes</code>. Any auxiliary lookup files (such as
   *     <code>ManagerTranslation.xml</code>) should be located inside the subdirectory called
   *     <code>auxiliary</code>.
   *     <p>Files within the schemes directory ending in <code>.xml</code> are read in and
   *     unmarshalled using <a href = "http://www.castor.org">Castor</a>.
   */
  public TDTEngine(String confdir)
      throws FileNotFoundException, MarshalException, ValidationException, TDTException {
    xmldir = confdir;

    long t = System.currentTimeMillis();
    File[] dir =
        new java.io.File(confdir + File.separator + "schemes").listFiles(new XMLFilenameFilter());
    // java.util.Arrays.sort(dir); // Sort it
    if (dir == null) throw new TDTException("Cannot find schemes in " + confdir);
    Unmarshaller unmar = new Unmarshaller();
    for (File f : dir) {
      EpcTagDataTranslation tdt =
          (EpcTagDataTranslation) unmar.unmarshal(EpcTagDataTranslation.class, new FileReader(f));

      initFromTDT(tdt);
    }

    // need to populate the hashmap gs1cpi from the ManagerTranslation.xml table in auxiliary.
    // Unmarshaller unmar = new Unmarshaller();
    GEPC64Table cpilookup =
        (GEPC64Table)
            unmar.unmarshal(
                GEPC64Table.class,
                new FileReader(
                    confdir
                        + File.separator
                        + "auxiliary"
                        + File.separator
                        + "ManagerTranslation.xml"));
    for (Enumeration e = cpilookup.enumerateEntry(); e.hasMoreElements(); ) {
      Entry entry = (Entry) e.nextElement();
      String comp = entry.getCompanyPrefix();
      String indx = Integer.toString(entry.getIndex());
      gs1cpi.put(indx, comp);
      gs1cpi.put(comp, indx);
    }

    // System.out.println("Loaded schemas in " +
    //		   (System.currentTimeMillis() - t)
    //		   + " millisecs");

  }
Beispiel #4
0
  /** convert from a particular scheme / level */
  private String convertLevel(
      Scheme tdtscheme,
      Level tdtlevel,
      String input,
      Map<String, String> inputParameters,
      LevelTypeList outboundlevel) {

    String outboundstring;
    Map<String, String> extraparams =
        //	    new NoisyMap
        (new HashMap<String, String>(inputParameters));

    // get the scheme's option key, which is the name of a
    // parameter whose value is matched to the option key of the
    // level.

    String optionkey = tdtscheme.getOptionKey();
    String optionValue = extraparams.get(optionkey);
    // the name of a parameter which allows the appropriate option
    // to be selected

    // now consider the various options within the scheme and
    // level for each option element inside the level, check
    // whether the pattern attribute matches as a regular
    // expression

    String matchingOptionKey = null;
    Option matchingOption = null;
    Matcher prefixMatcher = null;
    for (Enumeration e = tdtlevel.enumerateOption(); e.hasMoreElements(); ) {
      Option opt = (Option) e.nextElement();
      if (optionValue == null || optionValue.equals(opt.getOptionKey())) {
        // possible match

        Matcher matcher = Pattern.compile(opt.getPattern()).matcher(input);
        if (matcher.matches()) {
          if (prefixMatcher != null) throw new TDTException("Multiple patterns matched");
          prefixMatcher = matcher;
          matchingOptionKey = opt.getOptionKey();
          matchingOption = opt;
        }
      }
    }
    if (prefixMatcher == null) throw new TDTException("No patterns matched");

    optionValue = matchingOptionKey;

    for (Enumeration e = matchingOption.enumerateField(); e.hasMoreElements(); ) {
      Field field = (Field) e.nextElement();
      int seq = field.getSeq();

      String strfieldname = field.getName();
      int fieldlength = field.getLength();
      String strfieldvalue = prefixMatcher.group(seq);
      // System.out.println("   processing field " + strfieldname + " = '" + strfieldvalue + "'");

      if (field.getCompaction() == null) {
        // if compaction is null, treat field as an integer

        if (field.getCharacterSet() != null) { // if the character set is specified
          Matcher charsetmatcher =
              Pattern.compile("^" + field.getCharacterSet() + "$").matcher(strfieldvalue);
          if (!charsetmatcher.matches()) {
            throw new TDTException(
                "field "
                    + strfieldname
                    + " ("
                    + strfieldvalue
                    + ") does not conform to the allowed character set ("
                    + field.getCharacterSet()
                    + ") ");
          }
        }

        BigInteger bigvalue = null;

        if (tdtlevel.getType() == LevelTypeList.BINARY) { // if the input was BINARY
          bigvalue = new BigInteger(strfieldvalue, 2);
          extraparams.put(strfieldname, bigvalue.toString());
        } else {
          if (field.getDecimalMinimum() != null || field.getDecimalMaximum() != null)
            bigvalue = new BigInteger(strfieldvalue);
          extraparams.put(strfieldname, strfieldvalue);
        }

        if (field.getDecimalMinimum() != null) { // if the decimal minimum is specified
          BigInteger bigmin = new BigInteger(field.getDecimalMinimum());

          if (bigvalue.compareTo(bigmin)
              == -1) { // throw an exception if the field value is less than the decimal minimum
            throw new TDTException(
                "field "
                    + strfieldname
                    + " ("
                    + bigvalue
                    + ") is less than DecimalMinimum ("
                    + field.getDecimalMinimum()
                    + ") allowed");
          }
        }

        if (field.getDecimalMaximum() != null) { // if the decimal maximum is specified
          BigInteger bigmax = new BigInteger(field.getDecimalMaximum());

          if (bigvalue.compareTo(bigmax)
              == 1) { // throw an excpetion if the field value is greater than the decimal maximum
            throw new TDTException(
                "field "
                    + strfieldname
                    + " ("
                    + bigvalue
                    + ") is greater than DecimalMaximum ("
                    + field.getDecimalMaximum()
                    + ") allowed");
          }
        }

        // after extracting the field, it may be necessary to pad it.

        padField(extraparams, field);

      } else {
        // compaction is specified - interpret binary as a string value using a truncated byte per
        // character

        CompactionMethodList compaction = field.getCompaction();
        PadDirectionList padDir = field.getPadDir();
        String padchar = field.getPadChar();
        String s;
        if (compaction == CompactionMethodList.VALUE_5)
          // "5-bit"
          s = bin2uppercasefive(strfieldvalue);
        else if (compaction == CompactionMethodList.VALUE_4)
          // 6-bit
          s = bin2alphanumsix(strfieldvalue);
        else if (compaction == CompactionMethodList.VALUE_3)
          // 7-bit
          s = bin2asciiseven(strfieldvalue);
        else if (compaction == CompactionMethodList.VALUE_2)
          // 8-bit
          s = bin2bytestring(strfieldvalue);
        else throw new Error("unsupported compaction method " + compaction);
        extraparams.put(strfieldname, stripPadChar(s, padDir, padchar));
      }
    } // for each field;

    /**
     * the EXTRACT rules are performed after parsing the input, in order to determine additional
     * fields that are to be derived from the fields obtained by the pattern match process
     */
    int seq = 0;
    for (Enumeration e = tdtlevel.enumerateRule(); e.hasMoreElements(); ) {
      Rule tdtrule = (Rule) e.nextElement();
      if (tdtrule.getType() == ModeList.EXTRACT) {
        assert seq < tdtrule.getSeq() : "Rule out of sequence order";
        seq = tdtrule.getSeq();
        processRules(extraparams, tdtrule);
      }
    }

    /**
     * Now we need to consider the corresponding output level and output option. The scheme must
     * remain the same, as must the value of optionkey (to select the corresponding option element
     * nested within the required outbound level)
     */
    Level tdtoutlevel = findLevel(tdtscheme, outboundlevel);
    Option tdtoutoption = findOption(tdtoutlevel, optionValue);

    /**
     * the FORMAT rules are performed before formatting the output, in order to determine additional
     * fields that are required for preparation of the outbound format
     */
    seq = 0;
    for (Enumeration e = tdtoutlevel.enumerateRule(); e.hasMoreElements(); ) {
      Rule tdtrule = (Rule) e.nextElement();
      if (tdtrule.getType() == ModeList.FORMAT) {
        assert seq < tdtrule.getSeq() : "Rule out of sequence order";
        seq = tdtrule.getSeq();
        processRules(extraparams, tdtrule);
      }
    }

    /**
     * Now we need to ensure that all fields required for the outbound grammar are suitably padded
     * etc. processPadding takes care of firstly padding the non-binary fields if padChar and
     * padDir, length are specified then (if necessary) converting to binary and padding the binary
     * representation to the left with zeros if the bit string is has fewer bits than the bitLength
     * attribute specifies. N.B. TDTv1.1 will be more specific about bit-level padding rather than
     * assuming that it is always to the left with the zero bit.
     */

    // System.out.println(" prior to processPadding, " + extraparams);
    for (Enumeration e = tdtoutoption.enumerateField(); e.hasMoreElements(); ) {
      Field field = (Field) e.nextElement();
      // processPadding(extraparams, field, outboundlevel, tdtoutoption);

      padField(extraparams, field);
      if (outboundlevel == LevelTypeList.BINARY) binaryPadding(extraparams, field);
    }

    /**
     * Construct the output from the specified grammar (in ABNF format) together with the field
     * values stored in inputparams
     */
    outboundstring = buildGrammar(tdtoutoption.getGrammar(), extraparams);

    // System.out.println("final extraparams = " + extraparams);
    // System.out.println("returned " + outboundstring);
    return outboundstring;
  }