uri.java
来自「JAVA的一些源码 JAVA2 STANDARD EDITION DEVELO」· Java 代码 · 共 1,924 行 · 第 1/5 页
JAVA
1,924 行
StringBuffer uriSpecString = new StringBuffer(); if (m_scheme != null) { uriSpecString.append(m_scheme); uriSpecString.append(':'); } uriSpecString.append(getSchemeSpecificPart()); return uriSpecString.toString(); } /** * Get the indicator as to whether this URI uses the "generic URI" * syntax. * * @return true if this URI uses the "generic URI" syntax, false * otherwise */ public boolean isGenericURI() { // presence of the host (whether valid or empty) means // double-slashes which means generic uri return (m_host != null); } /** * Determine whether a scheme conforms to the rules for a scheme name. * A scheme is conformant if it starts with an alphanumeric, and * contains only alphanumerics, '+','-' and '.'. * * @return true if the scheme is conformant, false otherwise */ public static boolean isConformantSchemeName(String p_scheme) { if (p_scheme == null || p_scheme.trim().length() == 0) { return false; } if (!isAlpha(p_scheme.charAt(0))) { return false; } char testChar; int schemeLength = p_scheme.length(); for (int i = 1; i < schemeLength; ++i) { testChar = p_scheme.charAt(i); if (!isSchemeCharacter(testChar)) { return false; } } return true; } /** * Determine whether a string is syntactically capable of representing * a valid IPv4 address, IPv6 reference or the domain name of a network host. * A valid IPv4 address consists of four decimal digit groups separated by a * '.'. Each group must consist of one to three digits. See RFC 2732 Section 3, * and RFC 2373 Section 2.2, for the definition of IPv6 references. A hostname * consists of domain labels (each of which must begin and end with an alphanumeric * but may contain '-') separated & by a '.'. See RFC 2396 Section 3.2.2. * * @return true if the string is a syntactically valid IPv4 address, * IPv6 reference or hostname */ public static boolean isWellFormedAddress(String address) { if (address == null) { return false; } int addrLength = address.length(); if (addrLength == 0) { return false; } // Check if the host is a valid IPv6reference. if (address.startsWith("[")) { return isWellFormedIPv6Reference(address); } // Cannot start with a '.', '-', or end with a '-'. if (address.startsWith(".") || address.startsWith("-") || address.endsWith("-")) { return false; } // rightmost domain label starting with digit indicates IP address // since top level domain label can only start with an alpha // see RFC 2396 Section 3.2.2 int index = address.lastIndexOf('.'); if (address.endsWith(".")) { index = address.substring(0, index).lastIndexOf('.'); } if (index+1 < addrLength && isDigit(address.charAt(index+1))) { return isWellFormedIPv4Address(address); } else { // hostname = *( domainlabel "." ) toplabel [ "." ] // domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum // toplabel = alpha | alpha *( alphanum | "-" ) alphanum // RFC 2396 states that hostnames take the form described in // RFC 1034 (Section 3) and RFC 1123 (Section 2.1). According // to RFC 1034, hostnames are limited to 255 characters. if (addrLength > 255) { return false; } // domain labels can contain alphanumerics and '-" // but must start and end with an alphanumeric char testChar; int labelCharCount = 0; for (int i = 0; i < addrLength; i++) { testChar = address.charAt(i); if (testChar == '.') { if (!isAlphanum(address.charAt(i-1))) { return false; } if (i+1 < addrLength && !isAlphanum(address.charAt(i+1))) { return false; } labelCharCount = 0; } else if (!isAlphanum(testChar) && testChar != '-') { return false; } // RFC 1034: Labels must be 63 characters or less. else if (++labelCharCount > 63) { return false; } } } return true; } /** * <p>Determines whether a string is an IPv4 address as defined by * RFC 2373, and under the further constraint that it must be a 32-bit * address. Though not expressed in the grammar, in order to satisfy * the 32-bit address constraint, each segment of the address cannot * be greater than 255 (8 bits of information).</p> * * <p><code>IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT</code></p> * * @return true if the string is a syntactically valid IPv4 address */ public static boolean isWellFormedIPv4Address(String address) { int addrLength = address.length(); char testChar; int numDots = 0; int numDigits = 0; // make sure that 1) we see only digits and dot separators, 2) that // any dot separator is preceded and followed by a digit and // 3) that we find 3 dots // // RFC 2732 amended RFC 2396 by replacing the definition // of IPv4address with the one defined by RFC 2373. - mrglavas // // IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT // // One to three digits must be in each segment. for (int i = 0; i < addrLength; i++) { testChar = address.charAt(i); if (testChar == '.') { if ((i > 0 && !isDigit(address.charAt(i-1))) || (i+1 < addrLength && !isDigit(address.charAt(i+1)))) { return false; } numDigits = 0; if (++numDots > 3) { return false; } } else if (!isDigit(testChar)) { return false; } // Check that that there are no more than three digits // in this segment. else if (++numDigits > 3) { return false; } // Check that this segment is not greater than 255. else if (numDigits == 3) { char first = address.charAt(i-2); char second = address.charAt(i-1); if (!(first < '2' || (first == '2' && (second < '5' || (second == '5' && testChar <= '5'))))) { return false; } } } return (numDots == 3); } /** * <p>Determines whether a string is an IPv6 reference as defined * by RFC 2732, where IPv6address is defined in RFC 2373. The * IPv6 address is parsed according to Section 2.2 of RFC 2373, * with the additional constraint that the address be composed of * 128 bits of information.</p> * * <p><code>IPv6reference = "[" IPv6address "]"</code></p> * * <p>Note: The BNF expressed in RFC 2373 Appendix B does not * accurately describe section 2.2, and was in fact removed from * RFC 3513, the successor of RFC 2373.</p> * * @return true if the string is a syntactically valid IPv6 reference */ public static boolean isWellFormedIPv6Reference(String address) { int addrLength = address.length(); int index = 1; int end = addrLength-1; // Check if string is a potential match for IPv6reference. if (!(addrLength > 2 && address.charAt(0) == '[' && address.charAt(end) == ']')) { return false; } // Counter for the number of 16-bit sections read in the address. int [] counter = new int[1]; // Scan hex sequence before possible '::' or IPv4 address. index = scanHexSequence(address, index, end, counter); if (index == -1) { return false; } // Address must contain 128-bits of information. else if (index == end) { return (counter[0] == 8); } if (index+1 < end && address.charAt(index) == ':') { if (address.charAt(index+1) == ':') { // '::' represents at least one 16-bit group of zeros. if (++counter[0] > 8) { return false; } index += 2; // Trailing zeros will fill out the rest of the address. if (index == end) { return true; } } // If the second character wasn't ':', in order to be valid, // the remainder of the string must match IPv4Address, // and we must have read exactly 6 16-bit groups. else { return (counter[0] == 6) && isWellFormedIPv4Address(address.substring(index+1, end)); } } else { return false; } // 3. Scan hex sequence after '::'. int prevCount = counter[0]; index = scanHexSequence(address, index, end, counter); // We've either reached the end of the string, the address ends in // an IPv4 address, or it is invalid. scanHexSequence has already // made sure that we have the right number of bits. return (index == end) || (index != -1 && isWellFormedIPv4Address( address.substring((counter[0] > prevCount) ? index+1 : index, end))); } /** * Helper method for isWellFormedIPv6Reference which scans the * hex sequences of an IPv6 address. It returns the index of the * next character to scan in the address, or -1 if the string * cannot match a valid IPv6 address. * * @param address the string to be scanned * @param index the beginning index (inclusive) * @param end the ending index (exclusive) * @param counter a counter for the number of 16-bit sections read * in the address * * @return the index of the next character to scan, or -1 if the * string cannot match a valid IPv6 address */ private static int scanHexSequence (String address, int index, int end, int [] counter) { char testChar; int numDigits = 0; int start = index; // Trying to match the following productions: // hexseq = hex4 *( ":" hex4) // hex4 = 1*4HEXDIG for (; index < end; ++index) { testChar = address.charAt(index); if (testChar == ':') { // IPv6 addresses are 128-bit, so there can be at most eight sections. if (numDigits > 0 && ++counter[0] > 8) { return -1; } // This could be '::'. if (numDigits == 0 || ((index+1 < end) && address.charAt(index+1) == ':')) { return index; } numDigits = 0; } // This might be invalid or an IPv4address. If it's potentially an IPv4address, // backup to just after the last valid character that matches hexseq. else if (!isHex(testChar)) { if (testChar == '.' && numDigits < 4 && numDigits > 0 && counter[0] <= 6) { int back = index - numDigits - 1; return (back >= start) ? back : (back+1); } return -1; } // There can be at most 4 hex digits per group. else if (++numDigits > 4) { return -1; } } return (numDigits > 0 && ++counter[0] <= 8) ? end : -1; } /** * Determine whether a char is a digit. * * @return true if the char is betweeen '0' and '9', false otherwise */ private static boolean isDigit(char p_char) { return p_char >= '0' && p_char <= '9'; } /** * Determine whether a character is a hexadecimal character. * * @return true if the char is betweeen '0' and '9', 'a' and 'f' * or 'A' and 'F', false otherwise */ private static boolean isHex(char p_char) { return (p_char <= 'f' && (fgLookupTable[p_char] & ASCII_HEX_CHARACTERS) != 0); } /** * Determine whether a char is an alphabetic character: a-z or A-Z * * @return true if the char is alphabetic, false otherwise */ private static boolean isAlpha(char p_char) { return ((p_char >= 'a' && p_char <= 'z') || (p_char >= 'A' && p_char <= 'Z' )); } /** * Determine whether a char is an alphanumeric: 0-9, a-z or A-Z * * @return true if the char is alphanumeric, false otherwise */ private static boolean isAlphanum(char p_char) { return (p_char <= 'z' && (fgLookupTable[p_char] & MASK_ALPHA_NUMERIC) != 0); } /** * Determine whether a character is a reserved character: * ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '[', or ']' * * @return true if the string contains any reserved characters */ private static boolean isReservedCharacter(char p_char) { return (p_char <= ']' && (fgLookupTable[p_char] & RESERVED_CHARACTERS) != 0); } /** * Determine whether a char is an unreserved character. * * @return true if the char is unreserved, false otherwise */ private static boolean isUnreservedCharacter(char p_char) { return (p_char <= '~' && (fgLo
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?