All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.saxon.dotnet.DotNetComparator Maven / Gradle / Ivy

Go to download

Saxon a complete and conformant implementation of the XSLT 2.0, XQuery 1.0, and XPath 2.0 Recommendations published on 23 January 2007 by W3C

The newest version!
package net.sf.saxon.dotnet;

import cli.System.Globalization.CompareInfo;
import cli.System.Globalization.CompareOptions;
import cli.System.Globalization.SortKey;
import net.sf.saxon.sort.SubstringMatcher;

/**
 * A Collation implemented as a wrapper around a .NET CompareInfo object. Note that the
 * objects to be compared must be strings.
 */
public class DotNetComparator implements SubstringMatcher {

    private CompareInfo comparer;
    private CompareOptions options;

    /**
     * Create a collation based on a given .NET CompareInfo and CompareOptions
     * @param comparer the CompareInfo, which determines the language-specific
     * collation rules to be used
     * @param options Options to be used in performing comparisons, for example
     * whether they are to be case-blind and/or accent-blind
     */

    public DotNetComparator(CompareInfo comparer, CompareOptions options) {
        this.comparer = comparer;
        this.options = options;
    }

    /**
     * Compares its two arguments for order.  Returns a negative integer,
     * zero, or a positive integer as the first argument is less than, equal
     * to, or greater than the second.

*

* The implementor must ensure that sgn(compare(x, y)) == * -sgn(compare(y, x)) for all x and y. (This * implies that compare(x, y) must throw an exception if and only * if compare(y, x) throws an exception.)

*

* The implementor must also ensure that the relation is transitive: * ((compare(x, y)>0) && (compare(y, z)>0)) implies * compare(x, z)>0.

*

* Finally, the implementer must ensure that compare(x, y)==0 * implies that sgn(compare(x, z))==sgn(compare(y, z)) for all * z.

*

* It is generally the case, but not strictly required that * (compare(x, y)==0) == (x.equals(y)). Generally speaking, * any comparator that violates this condition should clearly indicate * this fact. The recommended language is "Note: this comparator * imposes orderings that are inconsistent with equals." * * @param o1 the first object to be compared. * @param o2 the second object to be compared. * @return a negative integer, zero, or a positive integer as the * first argument is less than, equal to, or greater than the * second. * @throws ClassCastException if the arguments' types prevent them from * being compared by this Comparator. */ public int compareStrings(String o1, String o2) { return comparer.Compare(o1, o2, options); } /** * Test whether one string is equal to another, according to the rules * of the XPath compare() function. The result is true if and only if the * compare() method returns zero: but the implementation may be more efficient * than calling compare and testing the result for zero * * @param s1 the first string * @param s2 the second string * @return true iff s1 equals s2 */ public boolean comparesEqual(String s1, String s2) { return comparer.Compare(s1, s2, options) == 0; } /** * Test whether one string contains another, according to the rules * of the XPath contains() function * * @param s1 the containing string * @param s2 the contained string * @return true iff s1 contains s2 */ public boolean contains(String s1, String s2) { return comparer.IndexOf(s1, s2, options) >= 0; } /** * Test whether one string ends with another, according to the rules * of the XPath ends-with() function * * @param s1 the containing string * @param s2 the contained string * @return true iff s1 ends with s2 */ public boolean endsWith(String s1, String s2) { return comparer.IsSuffix(s1, s2, options); } /** * Test whether one string starts with another, according to the rules * of the XPath starts-with() function * * @param s1 the containing string * @param s2 the contained string * @return true iff s1 starts with s2 */ public boolean startsWith(String s1, String s2) { return comparer.IsPrefix(s1, s2, options); } /** * Return the part of a string after a given substring, according to the rules * of the XPath substring-after() function * * @param s1 the containing string * @param s2 the contained string * @return the part of s1 that follows the first occurrence of s2 */ public String substringAfter(String s1, String s2) { int i = comparer.IndexOf(s1, s2, options); if (i<0) { return ""; }; // We need to know where the matched string ends. Start with a guess, that the matched string // is the same length as s2. If it's not, try shorter and longer strings until we find one that's // equal. The search strategy is designed on the assumption that the matched string is of similar // length to the input string. int pivot = i+s2.length(); if (comparer.Compare(s1.substring(i, pivot), s2, options) == 0) { return s1.substring(pivot); } int z=0; boolean reachedStart; boolean reachedEnd; while (true) { z++; reachedStart = pivot-z < i; reachedEnd = pivot+z >= s1.length(); if (!reachedEnd && comparer.Compare(s1.substring(i, pivot+z), s2, options) == 0) { return s1.substring(pivot+z); } if (!reachedStart && comparer.Compare(s1.substring(i, pivot-z), s2, options) == 0) { return s1.substring(pivot-z); } if (reachedStart && reachedEnd) { // shouldn't happen return ""; } } } /** * Return the part of a string before a given substring, according to the rules * of the XPath substring-before() function * * @param s1 the containing string * @param s2 the contained string * @return the part of s1 that precedes the first occurrence of s2 */ public String substringBefore(String s1, String s2) { int j = comparer.IndexOf(s1, s2, options); if (j<0) { return ""; }; return s1.substring(0, j); } /** * Return a collation key. This is a wrapper around the System.Globalization.Sortkey object, * where the wrapper implements the required comparison methods. */ public Object getCollationKey(String value) { final SortKey sortKey = comparer.GetSortKey(value, options); return new SortKeyWrapper(sortKey); } private static class SortKeyWrapper implements Comparable { private SortKey key; public SortKeyWrapper(SortKey key) { this.key = key; } public int compareTo(Object other) { return SortKey.Compare(key, (SortKey)other); } /** * Returns a hash code value for the object. */ public int hashCode() { byte[] data = key.get_KeyData(); int h = 0x7d6a8521; for (int i=0; i= 0; i--) { if (data1[i] != data2[i]) { return false; } } return true; } } } // // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License"); // you may not use this file except in compliance with the License. You may obtain a copy of the // License at http://www.mozilla.org/MPL/ // // Software distributed under the License is distributed on an "AS IS" basis, // WITHOUT WARRANTY OF ANY KIND, either express or implied. // See the License for the specific language governing rights and limitations under the License. // // The Original Code is: all this file. // // The Initial Developer of the Original Code is Michael H. Kay. // // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved. // // Contributor(s): none. //





© 2015 - 2024 Weber Informatics LLC | Privacy Policy