You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by ig...@apache.org on 2004/02/12 01:05:59 UTC
cvs commit: xml-xalan/java/src/org/apache/xml/utils LocaleUtility.java
igorh 2004/02/11 16:05:59
Modified: java/src/org/apache/xalan/xsltc/compiler Sort.java
java/src/org/apache/xalan/xsltc/dom NodeSortRecord.java
NodeSortRecordFactory.java
Added: java/src/org/apache/xml/utils LocaleUtility.java
Log:
Fix for Bugzilla Bug 26842.
Revision Changes Path
1.21 +55 -82 xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Sort.java
Index: Sort.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Sort.java,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- Sort.java 15 Oct 2003 18:16:29 -0000 1.20
+++ Sort.java 12 Feb 2004 00:05:59 -0000 1.21
@@ -110,10 +110,10 @@
private AttributeValue _order;
private AttributeValue _caseOrder;
private AttributeValue _dataType;
+ private String _lang; // bug! see 26869
private String _data = null;
- public String _lang;
- public String _country;
+
private String _className = null;
private ArrayList _closureVars = null;
@@ -185,11 +185,6 @@
if (val.length() == 0) val = "ascending";
_order = AttributeValue.create(this, val, parser);
- // Get the case order; default is language dependant
- val = getAttribute("case-order");
- if (val.length() == 0) val = "upper-first";
- _caseOrder = AttributeValue.create(this, val, parser);
-
// Get the sort data type; default is text
val = getAttribute("data-type");
if (val.length() == 0) {
@@ -206,16 +201,13 @@
}
_dataType = AttributeValue.create(this, val, parser);
- // Get the language whose sort rules we will use; default is env.dep.
- if ((val = getAttribute("lang")) != null) {
- try {
- StringTokenizer st = new StringTokenizer(val,"-",false);
- _lang = st.nextToken();
- _country = st.nextToken();
- }
- catch (NoSuchElementException e) { // ignore
- }
- }
+ _lang = getAttribute("lang"); // bug! see 26869
+ // val = getAttribute("lang");
+ // _lang = AttributeValue.create(this, val, parser);
+ // Get the case order; default is language dependant
+ val = getAttribute("case-order");
+ _caseOrder = AttributeValue.create(this, val, parser);
+
}
/**
@@ -251,6 +243,18 @@
_order.translate(classGen, methodGen);
}
+ public void translateCaseOrder(ClassGenerator classGen,
+ MethodGenerator methodGen) {
+ _caseOrder.translate(classGen, methodGen);
+ }
+
+ public void translateLang(ClassGenerator classGen,
+ MethodGenerator methodGen) {
+ final ConstantPoolGen cpg = classGen.getConstantPool();
+ final InstructionList il = methodGen.getInstructionList();
+ il.append(new PUSH(cpg, _lang)); // bug! see 26869
+ }
+
/**
* This method compiles code for the select expression for this
* xsl:sort element. The method is called from the static code-generating
@@ -365,6 +369,26 @@
sort.translateSortType(classGen, methodGen);
il.append(AASTORE);
}
+
+ il.append(new PUSH(cpg, nsorts));
+ il.append(new ANEWARRAY(cpg.addClass(STRING)));
+ for (int level = 0; level < nsorts; level++) {
+ final Sort sort = (Sort)sortObjects.elementAt(level);
+ il.append(DUP);
+ il.append(new PUSH(cpg, level));
+ sort.translateLang(classGen, methodGen);
+ il.append(AASTORE);
+ }
+
+ il.append(new PUSH(cpg, nsorts));
+ il.append(new ANEWARRAY(cpg.addClass(STRING)));
+ for (int level = 0; level < nsorts; level++) {
+ final Sort sort = (Sort)sortObjects.elementAt(level);
+ il.append(DUP);
+ il.append(new PUSH(cpg, level));
+ sort.translateCaseOrder(classGen, methodGen);
+ il.append(AASTORE);
+ }
il.append(new INVOKESPECIAL(
cpg.addMethodref(sortRecordFactoryClass, "<init>",
@@ -372,6 +396,8 @@
+ STRING_SIG
+ TRANSLET_INTF_SIG
+ "[" + STRING_SIG
+ + "[" + STRING_SIG
+ + "[" + STRING_SIG
+ "[" + STRING_SIG + ")V")));
// Initialize closure variables in sortRecordFactory
@@ -444,19 +470,24 @@
// Define a constructor for this class
final org.apache.bcel.generic.Type[] argTypes =
- new org.apache.bcel.generic.Type[5];
+ new org.apache.bcel.generic.Type[7];
argTypes[0] = Util.getJCRefType(DOM_INTF_SIG);
argTypes[1] = Util.getJCRefType(STRING_SIG);
argTypes[2] = Util.getJCRefType(TRANSLET_INTF_SIG);
argTypes[3] = Util.getJCRefType("[" + STRING_SIG);
argTypes[4] = Util.getJCRefType("[" + STRING_SIG);
+ argTypes[5] = Util.getJCRefType("[" + STRING_SIG);
+ argTypes[6] = Util.getJCRefType("[" + STRING_SIG);
- final String[] argNames = new String[5];
+ final String[] argNames = new String[7];
argNames[0] = DOCUMENT_PNAME;
argNames[1] = "className";
argNames[2] = TRANSLET_PNAME;
argNames[3] = "order";
argNames[4] = "type";
+ argNames[5] = "lang";
+ argNames[6] = "case_order";
+
InstructionList il = new InstructionList();
final MethodGenerator constructor =
@@ -472,12 +503,16 @@
il.append(new ALOAD(3));
il.append(new ALOAD(4));
il.append(new ALOAD(5));
+ il.append(new ALOAD(6));
+ il.append(new ALOAD(7));
il.append(new INVOKESPECIAL(cpg.addMethodref(NODE_SORT_FACTORY,
"<init>",
"(" + DOM_INTF_SIG
+ STRING_SIG
+ TRANSLET_INTF_SIG
+ "[" + STRING_SIG
+ + "[" + STRING_SIG
+ + "[" + STRING_SIG
+ "[" + STRING_SIG + ")V")));
il.append(RETURN);
@@ -614,69 +649,7 @@
il.append(new INVOKESPECIAL(cpg.addMethodref(NODE_SORT_RECORD,
"<init>", "()V")));
- final int initLocale = cpg.addMethodref("java/util/Locale",
- "<init>",
- "(Ljava/lang/String;"+
- "Ljava/lang/String;)V");
- final int getCollator = cpg.addMethodref(COLLATOR_CLASS,
- "getInstance",
- "(Ljava/util/Locale;)"+
- COLLATOR_SIG);
-
- final int setStrength = cpg.addMethodref(COLLATOR_CLASS,
- "setStrength", "(I)V");
-
- final int levels = sortObjects.size();
-
- /*
- final int levelsField = cpg.addFieldref(className, "_levels", "I");
- il.append(new PUSH(cpg, levels));
- il.append(new PUTSTATIC(levelsField));
- */
-
- // Compile code that initializes the locale
- String language = null;
- String country = null;
- Sort sort = (Sort)sortObjects.elementAt(0);
-
- for (int level = 0; level < levels; level++) {
- if (language == null && sort._lang != null) {
- language = sort._lang;
- }
- if (country == null && sort._country != null) {
- country = sort._country;
- }
- }
-
- final int collator =
- cpg.addFieldref(className, "_collator", COLLATOR_SIG);
- final int locale =
- cpg.addFieldref(className, "_locale", LOCALE_SIG);
-
- if (language != null) {
- // Create new Locale object on stack
- il.append(new NEW(cpg.addClass("java/util/Locale")));
- il.append(DUP);
- il.append(DUP);
- il.append(new PUSH(cpg, language));
- il.append(new PUSH(cpg, (country != null ? country : EMPTYSTRING)));
- il.append(new INVOKESPECIAL(initLocale));
- il.append(ALOAD_0);
- il.append(SWAP);
- il.append(new PUTFIELD(locale));
-
- // Use that Locale object to get the required Collator object
- il.append(new INVOKESTATIC(getCollator));
- il.append(ALOAD_0);
- il.append(SWAP);
- il.append(new PUTFIELD(collator));
- }
-
- il.append(ALOAD_0);
- il.append(new GETFIELD(collator));
- il.append(new ICONST(Collator.TERTIARY));
- il.append(new INVOKEVIRTUAL(setStrength));
il.append(RETURN);
1.15 +22 -23 xml-xalan/java/src/org/apache/xalan/xsltc/dom/NodeSortRecord.java
Index: NodeSortRecord.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/NodeSortRecord.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- NodeSortRecord.java 11 Dec 2003 23:23:09 -0000 1.14
+++ NodeSortRecord.java 12 Feb 2004 00:05:59 -0000 1.15
@@ -86,23 +86,20 @@
public static final int COMPARE_DESCENDING = 1;
/**
- * A reference to a locale. May be updated by subclass if the stylesheet
- * specifies a different language.
+ * A reference to a locales.
*/
- protected static final Locale DEFAULT_LOCALE = Locale.getDefault();
- protected Locale _locale = Locale.getDefault();
+ protected Locale[] _locale;
/**
- * A reference to a collator. May be updated by subclass if the stylesheet
- * specifies a different language (will be updated iff _locale is updated).
+ * A reference to a collators.
*/
- protected static final Collator DEFAULT_COLLATOR = Collator.getInstance();
- protected Collator _collator = DEFAULT_COLLATOR;
+ protected Collator[] _collator ;
protected CollatorFactory _collatorFactory;
protected int _levels = 1;
protected int[] _compareType;
protected int[] _sortOrder;
+ protected String[] _case_order;
private AbstractTranslet _translet = null;
@@ -121,9 +118,6 @@
*/
public NodeSortRecord(int node) {
_node = node;
- if (_locale != DEFAULT_LOCALE) {
- _collator = Collator.getInstance(_locale);
- }
}
public NodeSortRecord() {
@@ -135,8 +129,8 @@
* to the default constructor.
*/
public final void initialize(int node, int last, DOM dom,
- AbstractTranslet translet, int[] order, int[] type,
- NodeSortRecordFactory nsrFactory) throws TransletException
+ AbstractTranslet translet, int[] order, int[] type, final Locale[] locale, final Collator[] collator,
+ final String[] case_order, NodeSortRecordFactory nsrFactory) throws TransletException
{
_dom = dom;
_node = node;
@@ -149,7 +143,8 @@
_compareType = type;
_values = new Object[_levels];
-
+ _locale = locale;
+
// -- W. Eliot Kimber (eliot@isogen.com)
String colFactClassname =
System.getProperty("org.apache.xalan.xsltc.COLLATOR_FACTORY");
@@ -160,14 +155,18 @@
colFactClassname, ObjectFactory.findClassLoader(), true);
_collatorFactory = (CollatorFactory)candObj;
}
- catch (ClassNotFoundException e) {
- throw new TransletException(e);
+ catch (ClassNotFoundException e) {
+ throw new TransletException(e);
}
- }
- else {
- _collatorFactory = new CollatorFactoryBase();
+ for(int i = 0; i< _levels; i++){
+ _collator[i] = _collatorFactory.getCollator(_locale[i]);
+ }
+ }else {
+ _collator = collator;
}
- _collator = _collatorFactory.getCollator(_locale);
+
+
+ _case_order = case_order;
}
/**
@@ -195,7 +194,7 @@
// Get value from DOM if accessed for the first time
final String str = extractValueFromDOM(_dom, _node, level,
_translet, _last);
- final CollationKey key = _collator.getCollationKey(str);
+ final CollationKey key = _collator[level].getCollationKey(str);
_values[_scanned++] = key;
return(key);
}
@@ -257,7 +256,7 @@
* Returns the Collator used for text comparisons in this object.
* May be overridden by inheriting classes
*/
- public Collator getCollator() {
+ public Collator[] getCollator() {
return _collator;
}
1.11 +48 -26 xml-xalan/java/src/org/apache/xalan/xsltc/dom/NodeSortRecordFactory.java
Index: NodeSortRecordFactory.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/NodeSortRecordFactory.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- NodeSortRecordFactory.java 14 Aug 2003 16:27:43 -0000 1.10
+++ NodeSortRecordFactory.java 12 Feb 2004 00:05:59 -0000 1.11
@@ -69,6 +69,9 @@
import org.apache.xalan.xsltc.TransletException;
import org.apache.xalan.xsltc.runtime.AbstractTranslet;
import org.apache.xml.utils.ObjectFactory;
+import org.apache.xml.utils.LocaleUtility;
+import java.util.Locale;
+import java.text.Collator;
public class NodeSortRecordFactory {
@@ -80,6 +83,9 @@
private Class _class;
private int _order[];
private int _type[];
+ private Locale _locale[];
+ private Collator _collator[];
+ private String _case_order[];
private final AbstractTranslet _translet;
/**
@@ -89,35 +95,39 @@
* class), and the translet parameter is needed for methods called by
* this object.
*/
- public NodeSortRecordFactory(DOM dom, String className, Translet translet,
- String order[], String type[])
- throws TransletException {
- try {
- _dom = dom;
- _className = className;
- // This should return a Class definition if using TrAX
- _class = translet.getAuxiliaryClass(className);
- // This code is only run when the native API is used
- if (_class == null) {
+ public NodeSortRecordFactory(DOM dom, String className, Translet translet,
+ String order[], String type[], String lang[], String case_order[])
+ throws TransletException {
+ try {
+ _dom = dom;
+ _className = className;
+ // This should return a Class definition if using TrAX
+ _class = translet.getAuxiliaryClass(className);
+ // This code is only run when the native API is used
+ if (_class == null) {
_class = ObjectFactory.findProviderClass(
className, ObjectFactory.findClassLoader(), true);
}
- _translet = (AbstractTranslet)translet;
+ _translet = (AbstractTranslet)translet;
- int levels = order.length;
- _order = new int[levels];
- _type = new int[levels];
- for (int i = 0; i < levels; i++) {
- if (order[i].length() == DESCENDING)
- _order[i] = NodeSortRecord.COMPARE_DESCENDING;
- if (type[i].length() == NUMBER)
- _type[i] = NodeSortRecord.COMPARE_NUMERIC;
- }
- }
- catch (ClassNotFoundException e) {
- throw new TransletException(e);
- }
+ int levels = order.length;
+ _order = new int[levels];
+ _type = new int[levels];
+ for (int i = 0; i < levels; i++) {
+ if (order[i].length() == DESCENDING)
+ _order[i] = NodeSortRecord.COMPARE_DESCENDING;
+ if (type[i].length() == NUMBER)
+ _type[i] = NodeSortRecord.COMPARE_NUMERIC;
+ }
+ setLang(lang);
+ _case_order = case_order;
}
+ catch (ClassNotFoundException e) {
+ throw new TransletException(e);
+ }
+ }
+
+
/**
* Create an instance of a sub-class of NodeSortRecord. The name of this
@@ -133,11 +143,23 @@
final NodeSortRecord sortRecord =
(NodeSortRecord)_class.newInstance();
- sortRecord.initialize(node, last, _dom, _translet, _order, _type, this);
+ sortRecord.initialize(node, last, _dom, _translet, _order,
+ _type, _locale, _collator, _case_order, this);
return sortRecord;
}
public String getClassName() {
return _className;
+ }
+
+ private final void setLang(final String lang[]){
+
+ final int length = lang.length;
+ _locale = new Locale[length];
+ _collator = new Collator[length];
+ for(int i = 0; i< length; i++){
+ _locale[i] = LocaleUtility.langToLocale(lang[i]);
+ _collator[i] = Collator.getInstance(_locale[i] );
+ }
}
}
1.1 xml-xalan/java/src/org/apache/xml/utils/LocaleUtility.java
Index: LocaleUtility.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999-2003 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 "Xerces" 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) 1999, International
* Business Machines, Inc., http://www.apache.org. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
* @author Igor Hersht, igorh@ca.ibm.com
*/
package org.apache.xml.utils;
import java.util.Locale;
public class LocaleUtility {
/**
* IETF RFC 1766 tag separator
*/
public final static char IETF_SEPARATOR = '-';
public final static String EMPTY_STRING = "";
public static Locale langToLocale(String lang) {
if((lang == null) || lang.equals(EMPTY_STRING)){ // not specified => getDefault
return Locale.getDefault();
}
String language = EMPTY_STRING;
String country = EMPTY_STRING;
String variant = EMPTY_STRING;
int i1 = lang.indexOf(IETF_SEPARATOR);
if (i1 < 0) {
language = lang;
} else {
language = lang.substring(0, i1);
++i1;
int i2 = lang.indexOf(IETF_SEPARATOR, i1);
if (i2 < 0) {
country = lang.substring(i1);
} else {
country = lang.substring(i1, i2);
variant = lang.substring(i2+1);
}
}
if(language.length() == 2){
language = language.toLowerCase();
}else {
language = EMPTY_STRING;
}
if(country.length() == 2){
country = country.toUpperCase();
}else {
country = EMPTY_STRING;
}
if((variant.length() > 0) &&
((language.length() == 2) ||(country.length() == 2))){
variant = variant.toUpperCase();
}else{
variant = EMPTY_STRING;
}
return new Locale(language, country, variant );
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org