stylesheetimpl.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 932 行 · 第 1/2 页
JAVA
932 行
int size = map.length; for (int i = 0; i < size; i++) { Node child = (Node) sortKeys.get(i); env.setPosition(i + 1); // XXX: set last() as well for (int j = 0; j < sortList.length; j++) { Sort sort = sortList[j]; Object value = sort.sortValue(child, env); values[i * sortList.length + j] = value; } } boolean []ascendingList = new boolean[sortList.length]; for (int i = 0; i < ascendingList.length; i++) { Expr isAscending = sortList[i].getAscending(); if (isAscending == null || isAscending.evalBoolean(node, env)) ascendingList[i] = true; } Comparator []comparatorList = new Comparator[sortList.length]; for (int i = 0; i < comparatorList.length; i++) { Expr langExpr = sortList[i].getLang(); String lang = null; if (langExpr != null) { lang = langExpr.evalString(node, env); } if (lang != null) comparatorList[i] = getComparator(lang); } int []caseOrderList = new int[sortList.length]; for (int i = 0; i < caseOrderList.length; i++) { Expr caseOrder = sortList[i].getCaseOrder(); if (caseOrder == null) caseOrderList[i] = Sort.NO_CASE_ORDER; else if (caseOrder.evalBoolean(node, env)) caseOrderList[i] = Sort.UPPER_FIRST; else caseOrderList[i] = Sort.LOWER_FIRST; } sort(values, sortList, comparatorList, ascendingList, caseOrderList, 0, map.length, map, workMap); ArrayList sortedKeys = new ArrayList(); for (int i = 0; i < map.length; i++) sortedKeys.add(sortKeys.get(map[i])); return sortedKeys; } /** * Returns the comparator for the language. */ private Comparator getComparator(String lang) { Locale locale = getLocale(lang); return java.text.Collator.getInstance(locale); } /** * Returns the locale for the language. */ private Locale getLocale(String lang) { int p = lang.indexOf('-'); Locale locale = null; if (p < 0) { locale = new Locale(lang, ""); } else { String language = lang.substring(0, p); int q = lang.indexOf(p + 1, '-'); if (q < 0) { String country = lang.substring(p + 1); locale = new Locale(language, country); } else { String country = lang.substring(p + 1, q); String variant = lang.substring(q); locale = new Locale(language, country, variant); } } return locale; } /** * Sorts a subsequence. * * @param head the start of the subsequence * @param tail the tail of the subsequence */ private void sort(Object []values, Sort []sortList, Comparator []comparatorList, boolean []ascendingList, int []caseOrder, int head, int tail, int map[], int []workMap) { int length = tail - head; if (length <= 1) return; // shortcut when only have two items if (length == 2) { int a = map[head]; int b = map[head + 1]; if (lessThan(values, sortList, comparatorList, ascendingList, caseOrder, b, a)) { map[head] = b; map[head + 1] = a; } return; } // shortcut when only have three items else if (length == 3) { int a = map[head]; int b = map[head + 1]; int c = map[head + 2]; if (lessThan(values, sortList, comparatorList, ascendingList, caseOrder, b, a)) { map[head] = b; map[head + 1] = a; a = map[head]; b = map[head + 1]; } if (! lessThan(values, sortList, comparatorList, ascendingList, caseOrder, c, b)) { } else if (lessThan(values, sortList, comparatorList, ascendingList, caseOrder, c, a)) { map[head] = c; map[head + 1] = a; map[head + 2] = b; } else { map[head + 1] = c; map[head + 2] = b; } return; } int pivotIndex = (head + tail) / 2; int pivot = map[pivotIndex]; int top = tail; // values greater than the pivot value are put in the work map for (int i = tail - 1; i >= head; i--) { if (lessThan(values, sortList, comparatorList, ascendingList, caseOrder, pivot, map[i])) { workMap[--top] = map[i]; map[i] = -1; } } // if the pivot is the max, need to shift equals if (top == tail) { // values greater than the pivot value are put in the work map for (int i = tail - 1; i >= head; i--) { if (! lessThan(values, sortList, comparatorList, ascendingList, caseOrder, map[i], pivot)) { workMap[--top] = map[i]; map[i] = -1; } } // If all entries are equal to the pivot, we're done if (top == head) { for (int i = head; i < tail; i++) map[i] = workMap[i]; return; } } // shift down the values less than the pivot int center = head; for (int i = head; i < tail; i++) { if (map[i] >= 0) map[center++] = map[i]; } for (int i = center; i < tail; i++) map[i] = workMap[i]; sort(values, sortList, comparatorList, ascendingList, caseOrder, head, center, map, workMap); sort(values, sortList, comparatorList, ascendingList, caseOrder, center, tail, map, workMap); } /** * Swaps two items in the map. */ private void swap(int []map, int a, int b) { int ka = map[a]; int kb = map[b]; map[b] = ka; map[a] = kb; } /** * Returns true if the first value is strictly less than the second. */ private boolean lessThan(Object []values, Sort []sortList, Comparator []comparatorList, boolean []ascendingList, int []caseOrder, int ai, int bi) { int len = sortList.length; for (int i = 0; i < len; i++) { Object a = values[len * ai + i]; Object b = values[len * bi + i]; int cmp = sortList[i].cmp(a, b, comparatorList[i], ascendingList[i], caseOrder[i]); if (cmp < 0) return true; else if (cmp > 0) return false; } return false; } public void singleNumber(XslWriter out, Node node, Env env, AbstractPattern countPattern, AbstractPattern fromPattern, XslNumberFormat format) throws Exception { if (countPattern == null) countPattern = XPath.parseMatch(node.getNodeName()).getPattern(); IntArray numbers = new IntArray(); for (; node != null; node = node.getParentNode()) { if (countPattern.match(node, env)) { numbers.add(countPreviousSiblings(node, env, countPattern)); break; } if (fromPattern != null && fromPattern.match(node, env)) break; } if (fromPattern != null && ! findFromAncestor(node, env, fromPattern)) numbers.clear(); format.format(out, numbers); } public void multiNumber(XslWriter out, Node node, Env env, AbstractPattern countPattern, AbstractPattern fromPattern, XslNumberFormat format) throws Exception { if (countPattern == null) countPattern = XPath.parseMatch(node.getNodeName()).getPattern(); IntArray numbers = new IntArray(); for (; node != null; node = node.getParentNode()) { if (countPattern.match(node, env)) numbers.add(countPreviousSiblings(node, env, countPattern)); if (fromPattern != null && fromPattern.match(node, env)) break; } if (fromPattern != null && ! findFromAncestor(node, env, fromPattern)) numbers.clear(); format.format(out, numbers); } public void anyNumber(XslWriter out, Node node, Env env, AbstractPattern countPattern, AbstractPattern fromPattern, XslNumberFormat format) throws Exception { if (countPattern == null) countPattern = XPath.parseMatch(node.getNodeName()).getPattern(); IntArray numbers = new IntArray(); int count = 0; for (; node != null; node = XmlUtil.getPrevious(node)) { if (countPattern.match(node, env)) count++; if (fromPattern != null && fromPattern.match(node, env)) break; } numbers.add(count); if (fromPattern != null && ! findFromAncestor(node, env, fromPattern)) numbers.clear(); format.format(out, numbers); } public void exprNumber(XslWriter out, Node node, Env env, Expr expr, XslNumberFormat format) throws Exception { IntArray numbers = new IntArray(); numbers.add((int) expr.evalNumber(node, env)); format.format(out, numbers); } private int countPreviousSiblings(Node node, Env env, String name) { int count = 1; for (node = node.getPreviousSibling(); node != null; node = node.getPreviousSibling()) { if (node.getNodeType() == node.ELEMENT_NODE && node.getNodeName().equals(name)) count++; } return count; } private int countPreviousSiblings(Node node, Env env, AbstractPattern pattern) throws XPathException { int count = 1; for (node = node.getPreviousSibling(); node != null; node = node.getPreviousSibling()) { if (pattern.match(node, env)) count++; } return count; } private boolean findFromAncestor(Node node, Env env, AbstractPattern pattern) throws XPathException { for (; node != null; node = node.getParentNode()) if (pattern.match(node, env)) return true; return false; } /** * Strips the spaces from a tree. */ void stripSpaces(Node node) { Node child = node.getFirstChild(); while (child != null) { Node next = child.getNextSibling(); if (child instanceof Element) { stripSpaces(child); } else if (child instanceof Text) { String data = ((Text) child).getData(); boolean hasContent = false; for (int i = data.length() - 1; i >= 0; i--) { char ch = data.charAt(i); if (! XmlChar.isWhitespace(ch)) { hasContent = true; break; } } if (! hasContent && isStripSpaces(node)) { node.removeChild(child); } } child = next; } } /** * Returns true if the node is a pure whitespace text node. */ boolean isStripSpaces(Node node) { if (_strip == null) return false; for (Node ptr = node; ptr != null; ptr = ptr.getParentNode()) { if (ptr instanceof Element) { Element elt = (Element) ptr; String space = elt.getAttribute("xml:space"); if (space != null && space.equals("preserve")) return false; else if (space != null) break; } } String name = node.getNodeName(); if (_preserve.get(node.getNodeName()) != null) return false; else if (_strip.get(node.getNodeName()) != null) return true; CauchoNode cnode = (CauchoNode) node; String nsStar = cnode.getPrefix(); if (_preservePrefix.get(nsStar) != null) return false; else if (_stripPrefix.get(nsStar) != null) return true; return _strip.get("*") != null; } /** * Merges two template arrays into the final one. */ protected static Template []mergeTemplates(Template []star, Template []templates) { Template []merged = new Template[star.length + templates.length]; int i = 0; int j = 0; int k = 0; while (i < star.length && j < templates.length) { if (star[i].compareTo(templates[j]) > 0) merged[k++] = star[i++]; else merged[k++] = templates[j++]; } for (; i < star.length; i++) merged[k++] = star[i]; for (; j < templates.length; j++) merged[k++] = templates[j]; return merged; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?