maskformatter.java

来自「linux下建立JAVA虚拟机的源码KAFFE」· Java 代码 · 共 584 行 · 第 1/2 页

JAVA
584
字号
        }      }  }    /**   * Parses the text using the mask, valid characters, and invalid characters   * to determine the appropriate Object to return.  This strips the literal   * characters if necessary and invokes super.stringToValue.  If the paramter   * is invalid for the current mask and valid/invalid character sets this    * method will throw a ParseException.   *    * @param value the String to parse   * @throws ParseException if value doesn't match the mask and valid/invalid   * character sets   */  public Object stringToValue (String value) throws ParseException  {    int vLength = value.length();        // For value to be a valid it must be the same length as the mask    // note this doesn't take into account symbols that occupy more than     // one character, this is something we may possibly need to fix.    if (maskLength != vLength)      throw new ParseException ("stringToValue passed invalid value", vLength);        // Check if the value is valid according to the mask and valid/invalid     // sets.    try    {      convertValue(value, false);          }    catch (ParseException pe)    {      throw new ParseException("stringToValue passed invalid value",                                 pe.getErrorOffset());    }        if (!getValueContainsLiteralCharacters())      value = stripLiterals(value);    return super.stringToValue(value);  }    /**   * Strips the literal characters from the given String.   * @param value the String to strip   * @return the stripped String   */  String stripLiterals(String value)  {    StringBuffer result = new StringBuffer();    for (int i = 0; i < value.length(); i++)      {        // Only append the characters that don't correspond to literal        // characters in the mask.        switch (mask.charAt(i))          {          case NUM_CHAR:          case UPPERCASE_CHAR:          case LOWERCASE_CHAR:          case ALPHANUM_CHAR:          case LETTER_CHAR:          case HEX_CHAR:          case ANYTHING_CHAR:            result.append(value.charAt(i));            break;          default:          }      }    return result.toString();  }    /**   * Returns a String representation of the Object value based on the mask.   *    * @param value the value to convert   * @throws ParseException if value is invalid for this mask and valid/invalid   * character sets   */  public String valueToString (Object value) throws ParseException  {    String result = super.valueToString(value);    int rLength = result.length();        // If value is longer than the mask, truncate it.  Note we may need to     // account for symbols that are more than one character long.    if (rLength > maskLength)      result = result.substring(0, maskLength);        // Verify the validity and convert to upper/lowercase as needed.    result = convertValue(result, true);            if (rLength < maskLength)      return pad(result, rLength);        return result;  }    /**   * This method takes in a String and runs it through the mask to make   * sure that it is valid.  If <code>convert</code> is true, it also   * converts letters to upper/lowercase as required by the mask.   * @param value the String to convert   * @param convert true if we should convert letters to upper/lowercase   * @return the converted String   * @throws ParseException if the given String isn't valid for the mask   */  String convertValue(String value, boolean convert) throws ParseException  {    StringBuffer result = new StringBuffer(value);    char markChar;    char resultChar;    boolean literal;    // this boolean is specifically to avoid calling the isCharValid method    // when neither invalidChars or validChars has been set    boolean checkCharSets = (invalidChars != null || validChars != null);    for (int i = 0, j = 0; i < value.length(); i++, j++)      {        literal = false;        resultChar = result.charAt(i);        // This switch block on the mask character checks that the character         // within <code>value</code> at that point is valid according to the        // mask and also converts to upper/lowercase as needed.        switch (mask.charAt(j))          {          case NUM_CHAR:            if (!Character.isDigit(resultChar))              throw new ParseException("Number expected", i);            break;          case UPPERCASE_CHAR:            if (!Character.isLetter(resultChar))              throw new ParseException("Letter expected", i);            if (convert)              result.setCharAt(i, Character.toUpperCase(resultChar));            break;          case LOWERCASE_CHAR:            if (!Character.isLetter(resultChar))              throw new ParseException("Letter expected", i);            if (convert)              result.setCharAt(i, Character.toLowerCase(resultChar));            break;          case ALPHANUM_CHAR:            if (!Character.isLetterOrDigit(resultChar))              throw new ParseException("Letter or number expected", i);            break;          case LETTER_CHAR:            if (!Character.isLetter(resultChar))              throw new ParseException("Letter expected", i);            break;          case HEX_CHAR:            if (hexString.indexOf(resultChar) == -1)              throw new ParseException("Hexadecimal character expected", i);            break;          case ANYTHING_CHAR:            break;          case ESCAPE_CHAR:            // Escape character, check the next character to make sure that             // the literals match            j++;            literal = true;            if (resultChar != mask.charAt(j))              throw new ParseException ("Invalid character: "+resultChar, i);            break;          default:            literal = true;            if (!getValueContainsLiteralCharacters() && convert)              throw new ParseException ("Invalid character: "+resultChar, i);            else if (resultChar != mask.charAt(j))              throw new ParseException ("Invalid character: "+resultChar, i);          }        // If necessary, check if the character is valid.        if (!literal && checkCharSets && !isCharValid(resultChar))          throw new ParseException("invalid character: "+resultChar, i);      }    return result.toString();  }    /**   * Convenience method used by many other methods to check if a character is    * valid according to the mask, the validChars, and the invalidChars.  To   * be valid a character must:   * 1. be allowed by the mask   * 2. be present in any non-null validChars String   * 3. not be present in any non-null invalidChars String   * @param testChar the character to test   * @return true if the character is valid   */  boolean isCharValid(char testChar)  {    char lower = Character.toLowerCase(testChar);    char upper = Character.toUpperCase(testChar);    // If validChars isn't null, the character must appear in it.    if (validChars != null)      if (validChars.indexOf(lower) == -1 && validChars.indexOf(upper) == -1)        return false;    // If invalidChars isn't null, the character must not appear in it.    if (invalidChars != null)      if (invalidChars.indexOf(lower) != -1          || invalidChars.indexOf(upper) != -1)        return false;    return true;  }    /**   * Pads the value with literals, the placeholder String and/or placeholder   * character as appropriate.   * @param value the value to pad   * @param currLength the current length of the value   * @return the padded String   */  String pad (String value, int currLength)  {    StringBuffer result = new StringBuffer(value);    int index = currLength;    while (result.length() < maskLength)      {        // The character used to pad may be a literal, a character from the         // place holder string, or the place holder character.  getPadCharAt        // will find the proper one for us.        result.append (getPadCharAt(index));        index++;      }    return result.toString();  }  /**   * Returns the character with which to pad the value at the given index   * position.  If the mask has a literal at this position, this is returned   * otherwise if the place holder string is initialized and is longer than    * <code>i</code> characters then the character at position <code>i</code>   * from this String is returned.  Else, the place holder character is    * returned.   * @param i the index at which we want to pad the value   * @return the character with which we should pad the value   */  char getPadCharAt(int i)  {    boolean escaped = false;    int target = i;    char maskChar;    int holderLength = placeHolder == null ? -1 : placeHolder.length();    // We must iterate through the mask from the beginning, because the given    // index doesn't account for escaped characters.  For example, with the     // mask "1A'A''A1" index 2 refers to the literalized A, not to the     // single quotation.    for (int n = 0; n < mask.length(); n++)      {        maskChar = mask.charAt(n);        if (maskChar == ESCAPE_CHAR && !escaped)          {            target++;            escaped = true;          }        else if (escaped == true)          {            // Check if target == n which means we've come to the character            // we want to return and since it is a literal (because escaped             // is true), we return it.            if (target == n)              return maskChar;            escaped = false;          }        if (target == n)          {            // We've come to the character we want to return.  It wasn't            // escaped so if it isn't a literal we should return either            // the character from place holder string or the place holder            // character, depending on whether or not the place holder            // string is long enough.            switch (maskChar)            {            case NUM_CHAR:            case UPPERCASE_CHAR:            case LOWERCASE_CHAR:            case ALPHANUM_CHAR:            case LETTER_CHAR:            case HEX_CHAR:            case ANYTHING_CHAR:              if (holderLength > i)                return placeHolder.charAt(i);              else                return placeHolderChar;            default:              return maskChar;            }          }      }    // This shouldn't happen    throw new AssertionError("MaskFormatter.getMaskCharAt failed");  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?