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 ([EMAIL PROTECTED])
           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 [EMAIL PROTECTED]
   *
   * 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, [EMAIL PROTECTED]
   */
  
  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: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to