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