首页

关于apache的commons-fileupload包中参数解析ParameterParser、媒体类型工具类MimeUtility分析说明

标签:ParameterParser,MimeUtility,参数解析,媒体类型工具类,apache,ommons-fileupload     发布时间:2018-02-19   

一、前言

关于apachecommons-fileupload包中org.apache.commons.fileupload.ParameterParser参数解析类、org.apache.commons.fileupload.util.mime.MimeUtility媒体类型工具类。

二、源码说明

1.ParameterParser

package org.apache.commons.fileupload;@b@@b@import java.io.UnsupportedEncodingException;@b@import java.util.HashMap;@b@import java.util.Locale;@b@import java.util.Map;@b@import org.apache.commons.fileupload.util.mime.MimeUtility;@b@@b@public class ParameterParser@b@{@b@  private char[] chars = null;@b@@b@  private int pos = 0;@b@@b@  private int len = 0;@b@@b@  private int i1 = 0;@b@@b@  private int i2 = 0;@b@@b@  private boolean lowerCaseNames = false;@b@@b@  private boolean hasChar()@b@  {@b@    return (this.pos < this.len);@b@  }@b@@b@  private String getToken(boolean quoted)@b@  {@b@    while ((this.i1 < this.i2) && (Character.isWhitespace(this.chars[this.i1]))) {@b@      this.i1 += 1;@b@    }@b@@b@    while ((this.i2 > this.i1) && (Character.isWhitespace(this.chars[(this.i2 - 1)]))) {@b@      this.i2 -= 1;@b@    }@b@@b@    if ((quoted) && (this.i2 - this.i1 >= 2) && (this.chars[this.i1] == '"') && (this.chars[(this.i2 - 1)] == '"'))@b@    {@b@      this.i1 += 1;@b@      this.i2 -= 1;@b@    }@b@    String result = null;@b@    if (this.i2 > this.i1) {@b@      result = new String(this.chars, this.i1, this.i2 - this.i1);@b@    }@b@    return result;@b@  }@b@@b@  private boolean isOneOf(char ch, char[] charray)@b@  {@b@    boolean result = false;@b@    for (char element : charray) {@b@      if (ch == element) {@b@        result = true;@b@        break;@b@      }@b@    }@b@    return result;@b@  }@b@@b@  private String parseToken(char[] terminators)@b@  {@b@    this.i1 = this.pos;@b@    this.i2 = this.pos;@b@    while (hasChar()) {@b@      char ch = this.chars[this.pos];@b@      if (isOneOf(ch, terminators)) {@b@        break;@b@      }@b@      this.i2 += 1;@b@      this.pos += 1;@b@    }@b@    return getToken(false);@b@  }@b@@b@  private String parseQuotedToken(char[] terminators)@b@  {@b@    this.i1 = this.pos;@b@    this.i2 = this.pos;@b@    boolean quoted = false;@b@    boolean charEscaped = false;@b@    while (hasChar()) {@b@      char ch = this.chars[this.pos];@b@      if ((!(quoted)) && (isOneOf(ch, terminators))) {@b@        break;@b@      }@b@      if ((!(charEscaped)) && (ch == '"')) {@b@        quoted = !(quoted);@b@      }@b@      charEscaped = (!(charEscaped)) && (ch == '\\');@b@      this.i2 += 1;@b@      this.pos += 1;@b@    }@b@@b@    return getToken(true);@b@  }@b@@b@  public boolean isLowerCaseNames()@b@  {@b@    return this.lowerCaseNames;@b@  }@b@@b@  public void setLowerCaseNames(boolean b)@b@  {@b@    this.lowerCaseNames = b;@b@  }@b@@b@  public Map<String, String> parse(String str, char[] separators)@b@  {@b@    if ((separators == null) || (separators.length == 0)) {@b@      return new HashMap();@b@    }@b@    char separator = separators[0];@b@    if (str != null) {@b@      int idx = str.length();@b@      for (char separator2 : separators) {@b@        int tmp = str.indexOf(separator2);@b@        if ((tmp != -1) && (tmp < idx)) {@b@          idx = tmp;@b@          separator = separator2;@b@        }@b@      }@b@    }@b@    return parse(str, separator);@b@  }@b@@b@  public Map<String, String> parse(String str, char separator)@b@  {@b@    if (str == null) {@b@      return new HashMap();@b@    }@b@    return parse(str.toCharArray(), separator);@b@  }@b@@b@  public Map<String, String> parse(char[] charArray, char separator)@b@  {@b@    if (charArray == null) {@b@      return new HashMap();@b@    }@b@    return parse(charArray, 0, charArray.length, separator);@b@  }@b@@b@  public Map<String, String> parse(char[] charArray, int offset, int length, char separator)@b@  {@b@    if (charArray == null) {@b@      return new HashMap();@b@    }@b@    HashMap params = new HashMap();@b@    this.chars = charArray;@b@    this.pos = offset;@b@    this.len = length;@b@@b@    String paramName = null;@b@    String paramValue = null;@b@    while (hasChar()) {@b@      paramName = parseToken(new char[] { '=', separator });@b@@b@      paramValue = null;@b@      if ((hasChar()) && (charArray[this.pos] == '=')) {@b@        this.pos += 1;@b@        paramValue = parseQuotedToken(new char[] { separator });@b@@b@        if (paramValue != null)@b@          try {@b@            paramValue = MimeUtility.decodeText(paramValue);@b@          }@b@          catch (UnsupportedEncodingException e)@b@          {@b@          }@b@      }@b@      if ((hasChar()) && (charArray[this.pos] == separator)) {@b@        this.pos += 1;@b@      }@b@      if ((paramName != null) && (paramName.length() > 0));@b@      if (this.lowerCaseNames) {@b@        paramName = paramName.toLowerCase(Locale.ENGLISH);@b@      }@b@@b@      params.put(paramName, paramValue);@b@    }@b@@b@    return params;@b@  }@b@}

2.MimeUtility

package org.apache.commons.fileupload.util.mime;@b@@b@import java.io.ByteArrayOutputStream;@b@import java.io.IOException;@b@import java.io.UnsupportedEncodingException;@b@import java.util.HashMap;@b@import java.util.Locale;@b@import java.util.Map;@b@@b@public final class MimeUtility@b@{@b@  private static final String US_ASCII_CHARSET = "US-ASCII";@b@  private static final String BASE64_ENCODING_MARKER = "B";@b@  private static final String QUOTEDPRINTABLE_ENCODING_MARKER = "Q";@b@  private static final String ENCODED_TOKEN_MARKER = "=?";@b@  private static final String ENCODED_TOKEN_FINISHER = "?=";@b@  private static final String LINEAR_WHITESPACE = " \t\r\n";@b@  private static final Map<String, String> MIME2JAVA = new HashMap();@b@@b@  public static String decodeText(String text)@b@    throws UnsupportedEncodingException@b@  {@b@    if (text.indexOf("=?") < 0) {@b@      return text;@b@    }@b@@b@    int offset = 0;@b@    int endOffset = text.length();@b@@b@    int startWhiteSpace = -1;@b@    int endWhiteSpace = -1;@b@@b@    StringBuilder decodedText = new StringBuilder(text.length());@b@@b@    boolean previousTokenEncoded = false;@b@@b@    while (offset < endOffset) {@b@      char ch = text.charAt(offset);@b@@b@      if (" \t\r\n".indexOf(ch) != -1) {@b@        startWhiteSpace = offset;@b@        while (true) { if (offset >= endOffset)@b@            break label229;@b@          ch = text.charAt(offset);@b@          if (" \t\r\n".indexOf(ch) == -1) break;@b@          ++offset;@b@        }@b@@b@        label229: endWhiteSpace = offset;@b@      }@b@      else@b@      {@b@        int wordStart = offset;@b@@b@        while (offset < endOffset)@b@        {@b@          ch = text.charAt(offset);@b@          if (" \t\r\n".indexOf(ch) != -1) break;@b@          ++offset;@b@        }@b@@b@        String word = text.substring(wordStart, offset);@b@@b@        if (word.startsWith("=?"));@b@        try@b@        {@b@          String decodedWord = decodeWord(word);@b@@b@          if ((!(previousTokenEncoded)) && (startWhiteSpace != -1)) {@b@            decodedText.append(text.substring(startWhiteSpace, endWhiteSpace));@b@            startWhiteSpace = -1;@b@          }@b@@b@          previousTokenEncoded = true;@b@@b@          decodedText.append(decodedWord);@b@        }@b@        catch (ParseException e)@b@        {@b@          if (startWhiteSpace != -1) {@b@            decodedText.append(text.substring(startWhiteSpace, endWhiteSpace));@b@            startWhiteSpace = -1;@b@          }@b@@b@          previousTokenEncoded = false;@b@          decodedText.append(word);@b@        }@b@      }@b@    }@b@    return decodedText.toString();@b@  }@b@@b@  private static String decodeWord(String word)@b@    throws ParseException, UnsupportedEncodingException@b@  {@b@    if (!(word.startsWith("=?"))) {@b@      throw new ParseException("Invalid RFC 2047 encoded-word: " + word);@b@    }@b@@b@    int charsetPos = word.indexOf(63, 2);@b@    if (charsetPos == -1) {@b@      throw new ParseException("Missing charset in RFC 2047 encoded-word: " + word);@b@    }@b@@b@    String charset = word.substring(2, charsetPos).toLowerCase();@b@@b@    int encodingPos = word.indexOf(63, charsetPos + 1);@b@    if (encodingPos == -1) {@b@      throw new ParseException("Missing encoding in RFC 2047 encoded-word: " + word);@b@    }@b@@b@    String encoding = word.substring(charsetPos + 1, encodingPos);@b@@b@    int encodedTextPos = word.indexOf("?=", encodingPos + 1);@b@    if (encodedTextPos == -1) {@b@      throw new ParseException("Missing encoded text in RFC 2047 encoded-word: " + word);@b@    }@b@@b@    String encodedText = word.substring(encodingPos + 1, encodedTextPos);@b@@b@    if (encodedText.length() == 0) {@b@      return "";@b@    }@b@@b@    try@b@    {@b@      ByteArrayOutputStream out = new ByteArrayOutputStream(encodedText.length());@b@@b@      byte[] encodedData = encodedText.getBytes("US-ASCII");@b@@b@      if (encoding.equals("B"))@b@        Base64Decoder.decode(encodedData, out);@b@      else if (encoding.equals("Q"))@b@        QuotedPrintableDecoder.decode(encodedData, out);@b@      else {@b@        throw new UnsupportedEncodingException("Unknown RFC 2047 encoding: " + encoding);@b@      }@b@@b@      byte[] decodedData = out.toByteArray();@b@      return new String(decodedData, javaCharset(charset));@b@    } catch (IOException e) {@b@      throw new UnsupportedEncodingException("Invalid RFC 2047 encoding");@b@    }@b@  }@b@@b@  private static String javaCharset(String charset)@b@  {@b@    if (charset == null) {@b@      return null;@b@    }@b@@b@    String mappedCharset = (String)MIME2JAVA.get(charset.toLowerCase(Locale.ENGLISH));@b@@b@    if (mappedCharset == null) {@b@      return charset;@b@    }@b@    return mappedCharset;@b@  }@b@@b@  static@b@  {@b@    MIME2JAVA.put("iso-2022-cn", "ISO2022CN");@b@    MIME2JAVA.put("iso-2022-kr", "ISO2022KR");@b@    MIME2JAVA.put("utf-8", "UTF8");@b@    MIME2JAVA.put("utf8", "UTF8");@b@    MIME2JAVA.put("ja_jp.iso2022-7", "ISO2022JP");@b@    MIME2JAVA.put("ja_jp.eucjp", "EUCJIS");@b@    MIME2JAVA.put("euc-kr", "KSC5601");@b@    MIME2JAVA.put("euckr", "KSC5601");@b@    MIME2JAVA.put("us-ascii", "ISO-8859-1");@b@    MIME2JAVA.put("x-us-ascii", "ISO-8859-1");@b@  }@b@}