*/
public static StringCollator makeCollation(Configuration config, String uri, Properties props)
throws XPathException {
Collator collator = null;
StringCollator stringCollator = null;
// If a specific collation class is requested, this overrides everything else
String classAtt = props.getProperty("class");
if (classAtt != null) {
Object comparator = config.getInstance(classAtt, null);
if (comparator instanceof Collator) {
collator = (Collator)comparator;
} else if (comparator instanceof StringCollator) {
stringCollator = (StringCollator)comparator;
} else if (comparator instanceof Comparator) {
stringCollator = new NamedCollation(uri, (Comparator)comparator);
} else {
throw new XPathException("Requested collation class " + classAtt + " is not a Comparator");
}
}
// If rules are specified, create a RuleBasedCollator
if (collator == null && stringCollator == null) {
String rulesAtt = props.getProperty("rules");
if (rulesAtt != null) {
try {
collator = new RuleBasedCollator(rulesAtt);
} catch (ParseException e) {
throw new XPathException("Invalid collation rules: " + e.getMessage());
}
}
// Start with the lang attribute
if (collator == null) {
String langAtt = props.getProperty("lang");
if (langAtt!=null) {
collator = Collator.getInstance(getLocale(langAtt));
} else {
collator = Collator.getInstance(); // use default locale
}
}
}
if (collator != null) {
// See if there is a strength attribute
String strengthAtt = props.getProperty("strength");
if (strengthAtt!=null) {
if (strengthAtt.equals("primary")) {
collator.setStrength(Collator.PRIMARY);
} else if (strengthAtt.equals("secondary")) {
collator.setStrength(Collator.SECONDARY);
} else if (strengthAtt.equals("tertiary")) {
collator.setStrength(Collator.TERTIARY);
} else if (strengthAtt.equals("identical")) {
collator.setStrength(Collator.IDENTICAL);
} else {
throw new XPathException("strength must be primary, secondary, tertiary, or identical");
}
}
// Look for the properties ignore-case, ignore-modifiers, ignore-width
String ignore = props.getProperty("ignore-width");
if (ignore != null) {
if (ignore.equals("yes") && strengthAtt == null) {
collator.setStrength(Collator.TERTIARY);
} else if (ignore.equals("no")) {
// no-op
} else {
throw new XPathException("ignore-width must be yes or no");
}
}
ignore = props.getProperty("ignore-case");
if (ignore != null && strengthAtt == null) {
if (ignore.equals("yes")) {
collator.setStrength(Collator.SECONDARY);
} else if (ignore.equals("no")) {
// no-op
} else {
throw new XPathException("ignore-case must be yes or no");
}
}
ignore = props.getProperty("ignore-modifiers");
if (ignore != null) {
if (ignore.equals("yes") && strengthAtt == null) {
collator.setStrength(Collator.PRIMARY);
} else if (ignore.equals("no")) {
// no-op
} else {
throw new XPathException("ignore-modifiers must be yes or no");
}
}
// The ignore-symbols property is ignored
// See if there is a decomposition attribute
String decompositionAtt = props.getProperty("decomposition");
if (decompositionAtt!=null) {
if (decompositionAtt.equals("none")) {
collator.setDecomposition(Collator.NO_DECOMPOSITION);
} else if (decompositionAtt.equals("standard")) {
collator.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
} else if (decompositionAtt.equals("full")) {
collator.setDecomposition(Collator.FULL_DECOMPOSITION);
} else {
throw new XPathException("decomposition must be non, standard, or full");
}
}
}
if (stringCollator == null) {
stringCollator = new NamedCollation(uri, collator);
}
// See if there is a case-order property
String caseOrder = props.getProperty("case-order");
if (caseOrder != null && !"#default".equals(caseOrder)) {
// force base collator to ignore case differences
if (collator != null) {
collator.setStrength(Collator.SECONDARY);
}
if (caseOrder.equals("lower-first")) {
stringCollator = new LowercaseFirstCollator(stringCollator);
} else if (caseOrder.equals("upper-first")) {
stringCollator = new UppercaseFirstCollator(stringCollator);