예제 #1
0
 /**
  * Descriptor default constructor. Default initial descriptor size is 20. It will grow as needed.
  * <br>
  * Note that the created empty descriptor is not a valid descriptor (the method {@link #isValid
  * isValid} returns <CODE>false</CODE>)
  */
 public DescriptorSupport() {
   if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
     MODELMBEAN_LOGGER.logp(
         Level.FINEST, DescriptorSupport.class.getName(), "DescriptorSupport()", "Constructor");
   }
   init(null);
 }
예제 #2
0
 /**
  * Returns a new Descriptor which is a duplicate of the Descriptor.
  *
  * @exception RuntimeOperationsException for illegal value for field Names or field Values. If the
  *     descriptor construction fails for any reason, this exception will be thrown.
  */
 @Override
 public synchronized Object clone() throws RuntimeOperationsException {
   if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
     MODELMBEAN_LOGGER.logp(Level.FINEST, DescriptorSupport.class.getName(), "clone()", "Entry");
   }
   return (new DescriptorSupport(this));
 }
예제 #3
0
 /**
  * Descriptor constructor taking a Descriptor as parameter. Creates a new descriptor initialized
  * to the values of the descriptor passed in parameter.
  *
  * @param inDescr the descriptor to be used to initialize the constructed descriptor. If it is
  *     null or contains no descriptor fields, an empty Descriptor will be created.
  */
 public DescriptorSupport(DescriptorSupport inDescr) {
   if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
     MODELMBEAN_LOGGER.logp(
         Level.FINEST, DescriptorSupport.class.getName(), "Descriptor(Descriptor)", "Constructor");
   }
   if (inDescr == null) init(null);
   else init(inDescr.descriptorMap);
 }
예제 #4
0
  /**
   * Constructor taking fields in the <i>fieldName=fieldValue</i> format.
   *
   * @param fields String array with each element containing a field name and value. If this array
   *     is null or empty, then the default constructor will be executed. Null strings or empty
   *     strings will be ignored.
   *     <p>All field values should be Strings. If the field values are not Strings, the programmer
   *     will have to reset or convert these fields correctly.
   *     <p>Note: Each string should be of the form <i>fieldName=fieldValue</i>. The field name ends
   *     at the first {@code =} character; for example if the String is {@code a=b=c} then the field
   *     name is {@code a} and its value is {@code b=c}.
   * @exception RuntimeOperationsException for illegal value for field Names or field Values. The
   *     field must contain an "=". "=fieldValue", "fieldName", and "fieldValue" are illegal.
   *     FieldName cannot be null. "fieldName=" will cause the value to be null. If the descriptor
   *     construction fails for any reason, this exception will be thrown.
   */
  public DescriptorSupport(String... fields) {
    if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
      MODELMBEAN_LOGGER.logp(
          Level.FINEST,
          DescriptorSupport.class.getName(),
          "Descriptor(String... fields)",
          "Constructor");
    }
    init(null);
    if ((fields == null) || (fields.length == 0)) return;

    init(null);

    for (int i = 0; i < fields.length; i++) {
      if ((fields[i] == null) || (fields[i].equals(""))) {
        continue;
      }
      int eq_separator = fields[i].indexOf("=");
      if (eq_separator < 0) {
        // illegal if no = or is first character
        if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
          MODELMBEAN_LOGGER.logp(
              Level.FINEST,
              DescriptorSupport.class.getName(),
              "Descriptor(String... fields)",
              "Illegal arguments: field does not have " + "'=' as a name and value separator");
        }
        final String msg = "Field in invalid format: no equals sign";
        final RuntimeException iae = new IllegalArgumentException(msg);
        throw new RuntimeOperationsException(iae, msg);
      }

      String fieldName = fields[i].substring(0, eq_separator);
      String fieldValue = null;
      if (eq_separator < fields[i].length()) {
        // = is not in last character
        fieldValue = fields[i].substring(eq_separator + 1);
      }

      if (fieldName.equals("")) {
        if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
          MODELMBEAN_LOGGER.logp(
              Level.FINEST,
              DescriptorSupport.class.getName(),
              "Descriptor(String... fields)",
              "Illegal arguments: fieldName is empty");
        }

        final String msg = "Field in invalid format: no fieldName";
        final RuntimeException iae = new IllegalArgumentException(msg);
        throw new RuntimeOperationsException(iae, msg);
      }

      setField(fieldName, fieldValue);
    }
    if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
      MODELMBEAN_LOGGER.logp(
          Level.FINEST, DescriptorSupport.class.getName(), "Descriptor(String... fields)", "Exit");
    }
  }
예제 #5
0
  /**
   * Returns true if all of the fields have legal values given their names.
   *
   * <p>This implementation does not support interoperating with a directory or lookup service.
   * Thus, conforming to the specification, no checking is done on the <i>"export"</i> field.
   *
   * <p>Otherwise this implementation returns false if:
   *
   * <UL>
   *   <LI>name and descriptorType fieldNames are not defined, or null, or empty, or not String
   *   <LI>class, role, getMethod, setMethod fieldNames, if defined, are null or not String
   *   <LI>persistPeriod, currencyTimeLimit, lastUpdatedTimeStamp, lastReturnedTimeStamp if defined,
   *       are null, or not a Numeric String or not a Numeric Value {@literal >= -1}
   *   <LI>log fieldName, if defined, is null, or not a Boolean or not a String with value "t", "f",
   *       "true", "false". These String values must not be case sensitive.
   *   <LI>visibility fieldName, if defined, is null, or not a Numeric String or a not Numeric Value
   *       {@literal >= 1 and <= 4}
   *   <LI>severity fieldName, if defined, is null, or not a Numeric String or not a Numeric Value
   *       {@literal >= 0 and <= 6}<br>
   *   <LI>persistPolicy fieldName, if defined, is null, or not one of the following strings:<br>
   *       "OnUpdate", "OnTimer", "NoMoreOftenThan", "OnUnregister", "Always", "Never". These String
   *       values must not be case sensitive.<br>
   * </UL>
   *
   * @exception RuntimeOperationsException If the validity checking fails for any reason, this
   *     exception will be thrown.
   */
  public synchronized boolean isValid() throws RuntimeOperationsException {
    if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
      MODELMBEAN_LOGGER.logp(Level.FINEST, DescriptorSupport.class.getName(), "isValid()", "Entry");
    }
    // verify that the descriptor is valid, by iterating over each field...

    Set<Map.Entry<String, Object>> returnedSet = descriptorMap.entrySet();

    if (returnedSet == null) { // null descriptor, not valid
      if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
        MODELMBEAN_LOGGER.logp(
            Level.FINEST,
            DescriptorSupport.class.getName(),
            "isValid()",
            "Returns false (null set)");
      }
      return false;
    }
    // must have a name and descriptor type field
    String thisName = (String) (this.getFieldValue("name"));
    String thisDescType = (String) (getFieldValue("descriptorType"));

    if ((thisName == null)
        || (thisDescType == null)
        || (thisName.equals(""))
        || (thisDescType.equals(""))) {
      return false;
    }

    // According to the descriptor type we validate the fields contained

    for (Map.Entry<String, Object> currElement : returnedSet) {
      if (currElement != null) {
        if (currElement.getValue() != null) {
          // validate the field valued...
          if (validateField(
              (currElement.getKey()).toString(), (currElement.getValue()).toString())) {
            continue;
          } else {
            if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
              MODELMBEAN_LOGGER.logp(
                  Level.FINEST,
                  DescriptorSupport.class.getName(),
                  "isValid()",
                  "Field " + currElement.getKey() + "=" + currElement.getValue() + " is not valid");
            }
            return false;
          }
        }
      }
    }

    // fell through, all fields OK
    if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
      MODELMBEAN_LOGGER.logp(
          Level.FINEST, DescriptorSupport.class.getName(), "isValid()", "Returns true");
    }
    return true;
  }
예제 #6
0
  public synchronized void setFields(String[] fieldNames, Object[] fieldValues)
      throws RuntimeOperationsException {

    if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
      MODELMBEAN_LOGGER.logp(
          Level.FINEST,
          DescriptorSupport.class.getName(),
          "setFields(fieldNames,fieldValues)",
          "Entry");
    }

    if ((fieldNames == null)
        || (fieldValues == null)
        || (fieldNames.length != fieldValues.length)) {
      if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
        MODELMBEAN_LOGGER.logp(
            Level.FINEST,
            DescriptorSupport.class.getName(),
            "setFields(fieldNames,fieldValues)",
            "Illegal arguments");
      }

      final String msg = "fieldNames and fieldValues are null or invalid";
      final RuntimeException iae = new IllegalArgumentException(msg);
      throw new RuntimeOperationsException(iae, msg);
    }

    for (int i = 0; i < fieldNames.length; i++) {
      if ((fieldNames[i] == null) || (fieldNames[i].equals(""))) {
        if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
          MODELMBEAN_LOGGER.logp(
              Level.FINEST,
              DescriptorSupport.class.getName(),
              "setFields(fieldNames,fieldValues)",
              "Null field name encountered at element " + i);
        }
        final String msg = "fieldNames is null or invalid";
        final RuntimeException iae = new IllegalArgumentException(msg);
        throw new RuntimeOperationsException(iae, msg);
      }
      setField(fieldNames[i], fieldValues[i]);
    }
    if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
      MODELMBEAN_LOGGER.logp(
          Level.FINEST,
          DescriptorSupport.class.getName(),
          "setFields(fieldNames,fieldValues)",
          "Exit");
    }
  }
예제 #7
0
 /**
  * Descriptor constructor. Takes as parameter the initial capacity of the Map that stores the
  * descriptor fields. Capacity will grow as needed.<br>
  * Note that the created empty descriptor is not a valid descriptor (the method {@link #isValid
  * isValid} returns <CODE>false</CODE>).
  *
  * @param initNumFields The initial capacity of the Map that stores the descriptor fields.
  * @exception RuntimeOperationsException for illegal value for initNumFields (&lt;= 0)
  * @exception MBeanException Wraps a distributed communication Exception.
  */
 public DescriptorSupport(int initNumFields) throws MBeanException, RuntimeOperationsException {
   if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
     MODELMBEAN_LOGGER.logp(
         Level.FINEST,
         DescriptorSupport.class.getName(),
         "Descriptor(initNumFields = " + initNumFields + ")",
         "Constructor");
   }
   if (initNumFields <= 0) {
     if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
       MODELMBEAN_LOGGER.logp(
           Level.FINEST,
           DescriptorSupport.class.getName(),
           "Descriptor(initNumFields)",
           "Illegal arguments: initNumFields <= 0");
     }
     final String msg = "Descriptor field limit invalid: " + initNumFields;
     final RuntimeException iae = new IllegalArgumentException(msg);
     throw new RuntimeOperationsException(iae, msg);
   }
   init(null);
 }
예제 #8
0
  public synchronized String[] getFields() {
    if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
      MODELMBEAN_LOGGER.logp(
          Level.FINEST, DescriptorSupport.class.getName(), "getFields()", "Entry");
    }
    int numberOfEntries = descriptorMap.size();

    String[] responseFields = new String[numberOfEntries];
    Set<Map.Entry<String, Object>> returnedSet = descriptorMap.entrySet();

    int i = 0;

    if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
      MODELMBEAN_LOGGER.logp(
          Level.FINEST,
          DescriptorSupport.class.getName(),
          "getFields()",
          "Returning " + numberOfEntries + " fields");
    }
    for (Iterator<Map.Entry<String, Object>> iter = returnedSet.iterator(); iter.hasNext(); i++) {
      Map.Entry<String, Object> currElement = iter.next();

      if (currElement == null) {
        if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
          MODELMBEAN_LOGGER.logp(
              Level.FINEST, DescriptorSupport.class.getName(), "getFields()", "Element is null");
        }
      } else {
        Object currValue = currElement.getValue();
        if (currValue == null) {
          responseFields[i] = currElement.getKey() + "=";
        } else {
          if (currValue instanceof java.lang.String) {
            responseFields[i] = currElement.getKey() + "=" + currValue.toString();
          } else {
            responseFields[i] = currElement.getKey() + "=(" + currValue.toString() + ")";
          }
        }
      }
    }

    if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
      MODELMBEAN_LOGGER.logp(
          Level.FINEST, DescriptorSupport.class.getName(), "getFields()", "Exit");
    }

    return responseFields;
  }
예제 #9
0
  public synchronized Object getFieldValue(String fieldName) throws RuntimeOperationsException {

    if ((fieldName == null) || (fieldName.equals(""))) {
      if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
        MODELMBEAN_LOGGER.logp(
            Level.FINEST,
            DescriptorSupport.class.getName(),
            "getFieldValue(String fieldName)",
            "Illegal arguments: null field name");
      }
      final String msg = "Fieldname requested is null";
      final RuntimeException iae = new IllegalArgumentException(msg);
      throw new RuntimeOperationsException(iae, msg);
    }
    Object retValue = descriptorMap.get(fieldName);
    if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
      MODELMBEAN_LOGGER.logp(
          Level.FINEST,
          DescriptorSupport.class.getName(),
          "getFieldValue(String fieldName = " + fieldName + ")",
          "Returns '" + retValue + "'");
    }
    return (retValue);
  }
예제 #10
0
  /**
   * Returns a human readable string representing the descriptor. The string will be in the format
   * of "fieldName=fieldValue,fieldName2=fieldValue2,..."<br>
   * If there are no fields in the descriptor, then an empty String is returned.<br>
   * If a fieldValue is an object then the toString() method is called on it and its returned value
   * is used as the value for the field enclosed in parenthesis.
   *
   * @exception RuntimeOperationsException for illegal value for field Names or field Values. If the
   *     descriptor string fails for any reason, this exception will be thrown.
   */
  @Override
  public synchronized String toString() {
    if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
      MODELMBEAN_LOGGER.logp(
          Level.FINEST, DescriptorSupport.class.getName(), "toString()", "Entry");
    }

    String respStr = "";
    String[] fields = getFields();

    if ((fields == null) || (fields.length == 0)) {
      if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
        MODELMBEAN_LOGGER.logp(
            Level.FINEST, DescriptorSupport.class.getName(), "toString()", "Empty Descriptor");
      }
      return respStr;
    }

    if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
      MODELMBEAN_LOGGER.logp(
          Level.FINEST,
          DescriptorSupport.class.getName(),
          "toString()",
          "Printing " + fields.length + " fields");
    }

    for (int i = 0; i < fields.length; i++) {
      if (i == (fields.length - 1)) {
        respStr = respStr.concat(fields[i]);
      } else {
        respStr = respStr.concat(fields[i] + ", ");
      }
    }

    if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
      MODELMBEAN_LOGGER.logp(
          Level.FINEST,
          DescriptorSupport.class.getName(),
          "toString()",
          "Exit returning " + respStr);
    }

    return respStr;
  }
예제 #11
0
  public synchronized Object[] getFieldValues(String... fieldNames) {
    if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
      MODELMBEAN_LOGGER.logp(
          Level.FINEST,
          DescriptorSupport.class.getName(),
          "getFieldValues(String... fieldNames)",
          "Entry");
    }
    // if fieldNames == null return all values
    // if fieldNames is String[0] return no values

    final int numberOfEntries = (fieldNames == null) ? descriptorMap.size() : fieldNames.length;
    final Object[] responseFields = new Object[numberOfEntries];

    int i = 0;

    if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
      MODELMBEAN_LOGGER.logp(
          Level.FINEST,
          DescriptorSupport.class.getName(),
          "getFieldValues(String... fieldNames)",
          "Returning " + numberOfEntries + " fields");
    }

    if (fieldNames == null) {
      for (Object value : descriptorMap.values()) responseFields[i++] = value;
    } else {
      for (i = 0; i < fieldNames.length; i++) {
        if ((fieldNames[i] == null) || (fieldNames[i].equals(""))) {
          responseFields[i] = null;
        } else {
          responseFields[i] = getFieldValue(fieldNames[i]);
        }
      }
    }

    if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
      MODELMBEAN_LOGGER.logp(
          Level.FINEST,
          DescriptorSupport.class.getName(),
          "getFieldValues(String... fieldNames)",
          "Exit");
    }

    return responseFields;
  }
예제 #12
0
  public synchronized void setField(String fieldName, Object fieldValue)
      throws RuntimeOperationsException {

    // field name cannot be null or empty
    if ((fieldName == null) || (fieldName.equals(""))) {
      if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
        MODELMBEAN_LOGGER.logp(
            Level.FINEST,
            DescriptorSupport.class.getName(),
            "setField(fieldName,fieldValue)",
            "Illegal arguments: null or empty field name");
      }

      final String msg = "Field name to be set is null or empty";
      final RuntimeException iae = new IllegalArgumentException(msg);
      throw new RuntimeOperationsException(iae, msg);
    }

    if (!validateField(fieldName, fieldValue)) {
      if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
        MODELMBEAN_LOGGER.logp(
            Level.FINEST,
            DescriptorSupport.class.getName(),
            "setField(fieldName,fieldValue)",
            "Illegal arguments");
      }

      final String msg = "Field value invalid: " + fieldName + "=" + fieldValue;
      final RuntimeException iae = new IllegalArgumentException(msg);
      throw new RuntimeOperationsException(iae, msg);
    }

    if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
      MODELMBEAN_LOGGER.logp(
          Level.FINEST,
          DescriptorSupport.class.getName(),
          "setField(fieldName,fieldValue)",
          "Entry: setting '" + fieldName + "' to '" + fieldValue + "'");
    }

    // Since we do not remove any existing entry with this name,
    // the field will preserve whatever case it had, ignoring
    // any difference there might be in fieldName.
    descriptorMap.put(fieldName, fieldValue);
  }
예제 #13
0
  /**
   * Constructor taking field names and field values. Neither array can be null.
   *
   * @param fieldNames String array of field names. No elements of this array can be null.
   * @param fieldValues Object array of the corresponding field values. Elements of the array can be
   *     null. The <code>fieldValue</code> must be valid for the <code>fieldName</code> (as defined
   *     in method {@link #isValid isValid})
   *     <p>Note: array sizes of parameters should match. If both arrays are empty, then an empty
   *     descriptor is created.
   * @exception RuntimeOperationsException for illegal value for field Names or field Values. The
   *     array lengths must be equal. If the descriptor construction fails for any reason, this
   *     exception will be thrown.
   */
  public DescriptorSupport(String[] fieldNames, Object[] fieldValues)
      throws RuntimeOperationsException {
    if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
      MODELMBEAN_LOGGER.logp(
          Level.FINEST,
          DescriptorSupport.class.getName(),
          "Descriptor(fieldNames,fieldObjects)",
          "Constructor");
    }

    if ((fieldNames == null)
        || (fieldValues == null)
        || (fieldNames.length != fieldValues.length)) {
      if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
        MODELMBEAN_LOGGER.logp(
            Level.FINEST,
            DescriptorSupport.class.getName(),
            "Descriptor(fieldNames,fieldObjects)",
            "Illegal arguments");
      }

      final String msg = "Null or invalid fieldNames or fieldValues";
      final RuntimeException iae = new IllegalArgumentException(msg);
      throw new RuntimeOperationsException(iae, msg);
    }

    /* populate internal structure with fields */
    init(null);
    for (int i = 0; i < fieldNames.length; i++) {
      // setField will throw an exception if a fieldName is be null.
      // the fieldName and fieldValue will be validated in setField.
      setField(fieldNames[i], fieldValues[i]);
    }
    if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
      MODELMBEAN_LOGGER.logp(
          Level.FINEST,
          DescriptorSupport.class.getName(),
          "Descriptor(fieldNames,fieldObjects)",
          "Exit");
    }
  }
예제 #14
0
  /* At some stage we should rewrite this code to be cleverer.  Using
  a StringTokenizer as we do means, first, that we accept a lot of
  bogus strings without noticing they are bogus, and second, that we
  split the string being parsed at characters like > even if they
  occur in the middle of a field value. */
  public DescriptorSupport(String inStr)
      throws MBeanException, RuntimeOperationsException, XMLParseException {
    /* parse an XML-formatted string and populate internal
     * structure with it */
    if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
      MODELMBEAN_LOGGER.logp(
          Level.FINEST,
          DescriptorSupport.class.getName(),
          "Descriptor(String = '" + inStr + "')",
          "Constructor");
    }
    if (inStr == null) {
      if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
        MODELMBEAN_LOGGER.logp(
            Level.FINEST,
            DescriptorSupport.class.getName(),
            "Descriptor(String = null)",
            "Illegal arguments");
      }
      final String msg = "String in parameter is null";
      final RuntimeException iae = new IllegalArgumentException(msg);
      throw new RuntimeOperationsException(iae, msg);
    }

    final String lowerInStr = inStr.toLowerCase();
    if (!lowerInStr.startsWith("<descriptor>") || !lowerInStr.endsWith("</descriptor>")) {
      throw new XMLParseException("No <descriptor>, </descriptor> pair");
    }

    // parse xmlstring into structures
    init(null);
    // create dummy descriptor: should have same size
    // as number of fields in xmlstring
    // loop through structures and put them in descriptor

    StringTokenizer st = new StringTokenizer(inStr, "<> \t\n\r\f");

    boolean inFld = false;
    boolean inDesc = false;
    String fieldName = null;
    String fieldValue = null;

    while (st.hasMoreTokens()) { // loop through tokens
      String tok = st.nextToken();

      if (tok.equalsIgnoreCase("FIELD")) {
        inFld = true;
      } else if (tok.equalsIgnoreCase("/FIELD")) {
        if ((fieldName != null) && (fieldValue != null)) {
          fieldName = fieldName.substring(fieldName.indexOf('"') + 1, fieldName.lastIndexOf('"'));
          final Object fieldValueObject = parseQuotedFieldValue(fieldValue);
          setField(fieldName, fieldValueObject);
        }
        fieldName = null;
        fieldValue = null;
        inFld = false;
      } else if (tok.equalsIgnoreCase("DESCRIPTOR")) {
        inDesc = true;
      } else if (tok.equalsIgnoreCase("/DESCRIPTOR")) {
        inDesc = false;
        fieldName = null;
        fieldValue = null;
        inFld = false;
      } else if (inFld && inDesc) {
        // want kw=value, eg, name="myname" value="myvalue"
        int eq_separator = tok.indexOf("=");
        if (eq_separator > 0) {
          String kwPart = tok.substring(0, eq_separator);
          String valPart = tok.substring(eq_separator + 1);
          if (kwPart.equalsIgnoreCase("NAME")) fieldName = valPart;
          else if (kwPart.equalsIgnoreCase("VALUE")) fieldValue = valPart;
          else { // xml parse exception
            final String msg = "Expected `name' or `value', got `" + tok + "'";
            throw new XMLParseException(msg);
          }
        } else { // xml parse exception
          final String msg = "Expected `keyword=value', got `" + tok + "'";
          throw new XMLParseException(msg);
        }
      }
    } // while tokens
    if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
      MODELMBEAN_LOGGER.logp(
          Level.FINEST, DescriptorSupport.class.getName(), "Descriptor(XMLString)", "Exit");
    }
  }