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 + -
显示快捷键?