<?xml version="1.0" standalone="no"?>
<!DOCTYPE s1 SYSTEM "../../style/dtd/document.dtd">
<!-- 
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 2001, Sun
 * Microsystems., http://www.sun.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 -->
  <s1 title="&lt;xsl:sort&gt;">
  <ul>
    <li><link anchor="functionality">Functionality</link></li>
    <li><link anchor="sort-class">The Sort class</link></li>
    <li><link anchor="sortingiterator-class">The SortingIterator class</link></li>
    <li><link anchor="nodesortrecord-class">The NodeSortRecord class</link></li>    
    <li><link anchor="nodesortrecordfactory-class">The NodeSortRecordFactory class</link></li>
  </ul>
  
  <anchor name="functionality"/>
  <s2 title="Functionality">

  <p>The <code>&lt;xsl:sort&gt;</code> element is used to define a sort key which
  specifies the order in which nodes selected by either
  <code>&lt;xsl:apply-templates&gt;</code> or <code>&lt;xsl:for-each&gt;</code> are
  processed. The nodes can be sorted either in numerical or alphabetic order,
  and the alphabetic order may vary depeinding on the language in use. The
  nodes can be sorted either in ascending or descending order.</p>

  </s2><anchor name="sort-class"/>
  <s2 title="The Sort class">

  <p>Static methods of the Sort class is responsible for generating the
  necessary code for invoking SortingIterators under
  <code>&lt;xsl:apply-templates&gt;</code> and <code>&lt;xsl:for-each&gt;</code>
  elements. Both these elements can have several <code>&lt;xsl:sort&gt;</code>
  child nodes defining primary, secondary, teriary, etc. keys. The code for
  <code>&lt;xsl:apply-templates&gt;</code> and <code>&lt;xsl:for-each&gt;</code>
  create  vectors containg a Sort object for each sort key. The object methods
  of the Sort object encapsulate a container for key-specific data (such as the
  sort key itself, sort order, sort type, and such) while the static methods
  take a vector of Sort objects and generate the actual code.</p>

  <p>The <code>translate()</code> method of the Sort object is never called. The
  vectors containing the Sort objects for a <code>&lt;xsl:apply-templates&gt;</code>
  or <code>&lt;xsl:for-each&gt;</code> element are instead passed to the static
  <code>translateSortIterator()</code> method. This method compiles code that
  instanciates a SortingIterator object that will pass on a node-set in a
  specific order to the code handling the <code>&lt;xsl:apply-templates&gt;</code>
  or <code>&lt;xsl:for-each&gt;</code> element.</p>

  </s2><anchor name="sortingiterator-class"/>
  <s2 title="The SortingIterator class">

  <p>The SortingIterator class is responsible for sorting nodes encapsulated in
  sort obects. These sort objects must be of a class inheriting from
  NodeSortRecord, a the SortingIterator object needs a factory object providing
  it with the correct type of objects:</p>

  <p><img src="sort_objects.gif" alt="sort_objects.gif"/></p>
  <p><ref>Figure 1: SortingIterator</ref></p>

  <p>The SortingIterator class is fairly dumb and leaves much of the work to the
  NodeSortRecord class. The iterator gets the NodeSortRecords from the factory
  object and sorts them using quicksort and calling <code>compareTo()</code> on
  pairs of NodeSortRecord objects.</p>

  </s2><anchor name="nodesortrecord-class"/>
  <s2 title="The NodeSortRecord class">

  <p>The static methods in the Sort class generates a class inheriting from
  NodeSortRecord, with the following overloaded methods:</p>

  <ul>
    <li><em>Class Constructor</em></li>
      <ul><li>The class constructor is overloaded to create sort-key global
      tables, such as an array containing the sort order for all the sort keys
      and another array containg all the sort types. Different sort order/types
      can be specified for the different levels of sort keys, but we assume that
      the same language is used for all levels.</li></ul>
      
    <li><code>extractValueFromDOM(int level)</code></li>
      <ul><li>This method is called by the SortingIterator object to extract the
      value for a specific sort key for a node. The SortingIterator will only
      use this method once and will cache the returned value for later use. The
      method will only be called if absultely necessary.</li></ul>

    <li><code>compareType(int level)</code></li>
      <ul><li>This method returns the sort type for one sort key level. Returns
      either <code>COMPARE_STRING</code> or <code>COMPARE_NUMERIC</code>.</li></ul>
    
    <li><code>sortOrder(int level)</code></li>
      <ul><li>This method returns the sort order for one sort key level. Returns
      either <code>COMPARE_ASCENDING</code> or <code>COMPARE_DESCENDING</code></li></ul>
    
    <li><code>getCollator(int level)</code></li>
      <ul><li>This method returns a Collator object for language-specific
      string comparisons. The same Collator is used for all levels of the key.
      </li></ul> 
  </ul>

  <p>The <code>compareTo()</code> method of the NodeSortRecord base class deserves
  a bit of attention. It takes its own node (from the this pointer) and another
  node and compares, if necessary, the values for all sort keys:</p>

  <source>
    /**
     * Compare this sort element to another. The first level is checked first,
     * and we proceed to the next level only if the first level keys are
     * identical (and so the key values may not even be extracted from the DOM)
     */
    public int compareTo(NodeSortRecord other) {
	int cmp;
    
	for (int level=0; level&lt;_levels; level++) {
	    
	    // Compare the two nodes either as numeric or text values
	    if (compareType(level) == COMPARE_NUMERIC) {
		final Double our = numericValue(level);
		final Double their = other.numericValue(level);
		if (our == null) return(-1);
		if (their == null) return(1);
		cmp = our.compareTo(their);
	    }
	    else {
		String our = stringValue(level);
		String their = other.stringValue(level);
		if (our == null) return(-1);
		if (their == null) return(1);
		cmp = getCollator().compare(our,their);
	    }
	    
	    // Return inverse compare value if inverse sort order
	    if (cmp != 0) {
		if (sortOrder(level) == COMPARE_DESCENDING)
		    return(0 - cmp);
		else
		    return(cmp);
	    }
	    
	}
	return(0);
    }
  </source>

  <p>The two methods <code>stringValue(int level)</code> and 
  <code>numericValue(int level)</code> return values for one level of the sort key
  of a node. These methods cache these values after they are first read so that
  the <code>DOM.getNodeValue()</code> is only called once. Also, the algorithm
  used for these two methods assure that <code>DOM.getNodeValue()</code> is only
  called when needed. The value for a node's secondary sort key is never
  retrieved if the node can be uniquely identified by its primary key.</p>

  </s2><anchor name="nodesortrecordfactory-class"/>
  <s2 title="The NodeSortRecordFactory class">

  <p>After the static methods of the Sort class has generated the new class for
  sort objects it generates code that instanciates a new NodeSortRecordFactory
  object. This object is passed as a parameter to SortingIterators constructor
  and is used by the iterator to generate the necessary sort objects.</p>

  </s2>
</s1>
