📄 rulebasedcollator.java
字号:
if (length > max_length) { max_length = length; insertion_point = i+1; } } if (insertion_point < 0) throw new ParseException("no insertion point found for " + starter, offset); if (max_length < starter.length()) { /* * We need to expand the first entry. It must be sorted * like if it was the reference key itself (like the spec * said. So the first entry is special: the element is * replaced by the specified text element for the sorting. * This text replace the old one for comparisons. However * to preserve the behaviour we replace the first key (corresponding * to the found prefix) by a new code rightly ordered in the * sequence. The rest of the subsequence must be appended * to the end of the sequence. */ CollationSorter sorter = (CollationSorter) patch.get(0); CollationSorter expansionPrefix = (CollationSorter) main.get(insertion_point-1); sorter.expansionOrdering = starter.substring(max_length); // Skip the first good prefix element main.add(insertion_point, sorter); /* * This is a new set of rules. Append to the list. */ patch.remove(0); insertion_point++; } // Now insert all elements of patch at the insertion point. for (int i = 0; i < patch.size(); i++) main.add(i+insertion_point, patch.get(i)); } /** * This method parses a string and build a set of sorting instructions. The parsing * may only be partial on the case the rules are to be merged sometime later. * * @param stop_on_reset If this parameter is true then the parser stops when it * encounters a reset instruction. In the other case, it tries to parse the subrules * and merged it in the same repository. * @param v Output vector for the set of instructions. * @param base_offset Offset in the string to begin parsing. * @param rules Rules to be parsed. * @return -1 if the parser reached the end of the string, an integer representing the * offset in the string at which it stopped parsing. * @throws ParseException if something turned wrong during the parsing. To get details * decode the message. */ private int subParseString(boolean stop_on_reset, ArrayList v, int base_offset, String rules) throws ParseException { boolean ignoreChars = (base_offset == 0); int operator = -1; StringBuffer sb = new StringBuffer(); boolean doubleQuote = false; boolean eatingChars = false; boolean nextIsModifier = false; boolean isModifier = false; int i; main_parse_loop: for (i = 0; i < rules.length(); i++) { char c = rules.charAt(i); int type = -1; if (!eatingChars && ((c >= 0x09 && c <= 0x0D) || (c == 0x20))) continue; isModifier = nextIsModifier; nextIsModifier = false; if (eatingChars && c != '\'') { doubleQuote = false; sb.append(c); continue; } if (doubleQuote && eatingChars) { sb.append(c); doubleQuote = false; continue; } switch (c) { case '!': throw new ParseException ("Modifier '!' is not yet supported by Classpath", i + base_offset); case '<': type = CollationSorter.GREATERP; break; case ';': type = CollationSorter.GREATERS; break; case ',': type = CollationSorter.GREATERT; break; case '=': type = CollationSorter.EQUAL; break; case '\'': eatingChars = !eatingChars; doubleQuote = true; break; case '@': if (ignoreChars) throw new ParseException ("comparison list has not yet been started. You may only use" + "(<,;=&)", i + base_offset); // Inverse the order of secondaries from now on. nextIsModifier = true; type = CollationSorter.INVERSE_SECONDARY; break; case '&': type = CollationSorter.RESET; if (stop_on_reset) break main_parse_loop; break; default: if (operator < 0) throw new ParseException ("operator missing at " + (i + base_offset), i + base_offset); if (! eatingChars && ((c >= 0x21 && c <= 0x2F) || (c >= 0x3A && c <= 0x40) || (c >= 0x5B && c <= 0x60) || (c >= 0x7B && c <= 0x7E))) throw new ParseException ("unquoted punctuation character '" + c + "'", i + base_offset); //type = ignoreChars ? CollationSorter.IGNORE : -1; sb.append(c); break; } if (type < 0) continue; if (operator < 0) { operator = type; continue; } if (sb.length() == 0 && !isModifier) throw new ParseException ("text element empty at " + (i+base_offset), i+base_offset); if (operator == CollationSorter.RESET) { /* Reposition in the sorting list at the position * indicated by the text element. */ String subrules = rules.substring(i); ArrayList sorted_rules = new ArrayList(); int idx; // Parse the subrules but do not iterate through all // sublist. This is the privilege of the first call. idx = subParseString(true, sorted_rules, base_offset+i, subrules); // Merge new parsed rules into the list. mergeRules(base_offset+i, sb.toString(), v, sorted_rules); sb.setLength(0); // Reset state to none. operator = -1; type = -1; // We have found a new subrule at 'idx' but it has not been parsed. if (idx >= 0) { i += idx-1; continue main_parse_loop; } else // No more rules. break main_parse_loop; } CollationSorter sorter = new CollationSorter(); if (operator == CollationSorter.GREATERP) ignoreChars = false; sorter.comparisonType = operator; sorter.textElement = sb.toString(); sorter.hashText = sorter.textElement.hashCode(); sorter.offset = base_offset+rules.length(); sorter.ignore = ignoreChars; sb.setLength(0); v.add(sorter); operator = type; } if (operator >= 0) { CollationSorter sorter = new CollationSorter(); int pos = rules.length() + base_offset; if ((sb.length() != 0 && nextIsModifier) || (sb.length() == 0 && !nextIsModifier && !eatingChars)) throw new ParseException("text element empty at " + pos, pos); if (operator == CollationSorter.GREATERP) ignoreChars = false; sorter.comparisonType = operator; sorter.textElement = sb.toString(); sorter.hashText = sorter.textElement.hashCode(); sorter.offset = base_offset+pos; sorter.ignore = ignoreChars; v.add(sorter); } if (i == rules.length()) return -1; else return i; } /** * This method creates a copy of this object. * * @return A copy of this object. */ public Object clone() { return super.clone(); } /** * This method completely parses a string 'rules' containing sorting rules. * * @param rules String containing the rules to be parsed. * @return A set of sorting instructions stored in a Vector. * @throws ParseException if something turned wrong during the parsing. To get details * decode the message. */ private ArrayList parseString(String rules) throws ParseException { ArrayList v = new ArrayList(); // result of the first subParseString is not absolute (may be -1 or a // positive integer). But we do not care. subParseString(false, v, 0, rules); return v; } /** * This method uses the sorting instructions built by {@link #parseString} * to build collation elements which can be directly used to sort strings. * * @param parsedElements Parsed instructions stored in a ArrayList. * @throws ParseException if the order of the instructions are not valid. */ private void buildCollationVector(ArrayList parsedElements) throws ParseException { int primary_seq = 0; int last_tertiary_seq = 0; short secondary_seq = 0; short tertiary_seq = 0; short equality_seq = 0; boolean inverseComparisons = false; final boolean DECREASING = false; final boolean INCREASING = true; boolean secondaryType = INCREASING; ArrayList v = new ArrayList(); // elts is completely sorted.element_loop: for (int i = 0; i < parsedElements.size(); i++) { CollationSorter elt = (CollationSorter) parsedElements.get(i); boolean ignoreChar = false; switch (elt.comparisonType) { case CollationSorter.GREATERP: primary_seq++; if (inverseComparisons) { secondary_seq = Short.MAX_VALUE; secondaryType = DECREASING; } else { secondary_seq = 0; secondaryType = INCREASING; } tertiary_seq = 0; equality_seq = 0; inverseComparisons = false; break; case CollationSorter.GREATERS: if (secondaryType == DECREASING) secondary_seq--; else secondary_seq++; tertiary_seq = 0; equality_seq = 0; break; case CollationSorter.INVERSE_SECONDARY: inverseComparisons = true; continue element_loop; case CollationSorter.GREATERT: tertiary_seq++; if (primary_seq == 0) last_tertiary_seq = tertiary_seq; equality_seq = 0; break; case CollationSorter.EQUAL: equality_seq++; break; case CollationSorter.RESET: throw new ParseException ("Invalid reached state 'RESET'. Internal error", elt.offset); default: throw new ParseException ("Invalid unknown state '" + elt.comparisonType + "'", elt.offset); } v.add(new CollationElement(elt.textElement, primary_seq,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -