International friendly string comparison with case-order : Collator « I18N « Java Tutorial

Java Tutorial
1. Language
2. Data Type
3. Operators
4. Statement Control
5. Class Definition
6. Development
7. Reflection
8. Regular Expressions
9. Collections
10. Thread
11. File
12. Generics
13. I18N
14. Swing
15. Swing Event
16. 2D Graphics
17. SWT
18. SWT 2D Graphics
19. Network
20. Database
21. Hibernate
22. JPA
23. JSP
24. JSTL
25. Servlet
26. Web Services SOA
27. EJB3
28. Spring
29. PDF
30. Email
31. J2ME
32. J2EE Application
33. XML
34. Design Pattern
35. Log
36. Security
37. Apache Common
38. Ant
39. JUnit
Java
Java Source Code / Java Documentation
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Tutorial » I18N » Collator 
13. 18. 5. International friendly string comparison with case-order
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * $Id: StringComparable.java 468655 2006-10-28 07:12:06Z minchau $
 */


import java.util.Vector;
import java.text.Collator;
import java.text.RuleBasedCollator;
import java.text.CollationElementIterator;
import java.util.Locale;
import java.text.CollationKey;


/**
* International friendly string comparison with case-order
 @author Igor Hersht, igorh@ca.ibm.com
*/
public class StringComparable implements Comparable  {
    
     public final static int UNKNOWN_CASE = -1;
     public final static int UPPER_CASE = 1;
     public final static int LOWER_CASE = 2;
     
     private  String m_text;
     private  Locale m_locale;
     private RuleBasedCollator m_collator;
     private String m_caseOrder;
     private int m_mask = 0xFFFFFFFF
     
    public StringComparable(final String text, final Locale locale, final Collator collator, final String caseOrder){
         m_text =  text;
         m_locale = locale;
         m_collator = (RuleBasedCollator)collator;
         m_caseOrder = caseOrder;
         m_mask = getMask(m_collator.getStrength());
    }
  
   public final static Comparable getComparatorfinal String text, final Locale locale, final Collator collator, final String caseOrder){
       if((caseOrder == null||(caseOrder.length() == 0)){// no case-order specified
            return  ((RuleBasedCollator)collator).getCollationKey(text);
       }else{
            return new StringComparable(text, locale, collator, caseOrder);
       }       
   }
   
   public final String toString(){return m_text;}
   
   public int compareTo(Object o) {
   final String pattern = ((StringComparable)o).toString();
   if(m_text.equals(pattern)){//Code-point equals 
      return 0;
   }
   final int savedStrength = m_collator.getStrength()
   int comp = 0;
      // Is there difference more significant than case-order?     
     if(((savedStrength == Collator.PRIMARY|| (savedStrength == Collator.SECONDARY))){  
         comp = m_collator.compare(m_text, pattern );     
     }else{// more than SECONDARY
         m_collator.setStrength(Collator.SECONDARY);
         comp = m_collator.compare(m_text, pattern );
         m_collator.setStrength(savedStrength);
     }
     if(comp != 0){//Difference more significant than case-order 
        return comp ; 
     }      
        
      // No difference more significant than case-order.     
      // Find case difference
       comp = getCaseDiff(m_text, pattern);
       if(comp != 0){  
           return comp;
       }else{// No case differences. Less significant difference could exist 
            return m_collator.compare(m_text, pattern );
       }      
  }
  
 
  private final int getCaseDiff (final String text, final String pattern){
     final int savedStrength = m_collator.getStrength();
     final int savedDecomposition = m_collator.getDecomposition();
     m_collator.setStrength(Collator.TERTIARY);// not to ignore case  
     m_collator.setDecomposition(Collator.CANONICAL_DECOMPOSITION );// corresponds NDF
     
    final int diff[] =getFirstCaseDiff (text, pattern, m_locale);
    m_collator.setStrength(savedStrength);// restore
    m_collator.setDecomposition(savedDecomposition)//restore
    if(diff != null){  
       if((m_caseOrder).equals("upper-first")){
            if(diff[0== UPPER_CASE){
                return -1;
            }else{
                return 1;
            }
       }else{// lower-first
            if(diff[0== LOWER_CASE){
                return -1;
            }else{
                return 1;
            }
       }
   }else{// No case differences
        return 0;
   }
    
  }
  
   
    
  private final int[] getFirstCaseDiff(final String text, final String pattern, final Locale locale){
        
        final CollationElementIterator targIter = m_collator.getCollationElementIterator(text);
        final CollationElementIterator patIter = m_collator.getCollationElementIterator(pattern);  
        int startTarg = -1;
        int endTarg = -1;
        int startPatt = -1;
        int endPatt = -1;
        final int done = getElement(CollationElementIterator.NULLORDER);
        int patternElement = 0, targetElement = 0;
        boolean getPattern = true, getTarget = true;
        
        while (true) { 
            if (getPattern){
                 startPatt = patIter.getOffset();
                 patternElement = getElement(patIter.next());
                 endPatt = patIter.getOffset();
            }
            if ((getTarget)){               
                 startTarg  = targIter.getOffset()
                 targetElement   = getElement(targIter.next())
                 endTarg  = targIter.getOffset();
            }
            getTarget = getPattern = true;                          
            if ((patternElement == done||targetElement == done)) {
                return null;                      
            else if (targetElement == 0) {
              getPattern = false;           
            else if (patternElement == 0) {
              getTarget = false;           
            else if (targetElement != patternElement) {// mismatch
                if((startPatt < endPatt&& (startTarg < endTarg)){
                    final String  subText = text.substring(startTarg, endTarg);
                    final String  subPatt = pattern.substring(startPatt, endPatt);
                    final String  subTextUp = subText.toUpperCase(locale);
                    final String  subPattUp = subPatt.toUpperCase(locale);
                    if(m_collator.compare(subTextUp, subPattUp!= 0){ // not case diffference
                        continue;
                    }
                    
                    int diff[] {UNKNOWN_CASE, UNKNOWN_CASE};
                    if(m_collator.compare(subText, subTextUp== 0){
                        diff[0= UPPER_CASE;
                    }else if(m_collator.compare(subText, subText.toLowerCase(locale)) == 0){
                       diff[0= LOWER_CASE; 
                    }
                    if(m_collator.compare(subPatt, subPattUp== 0){
                        diff[1= UPPER_CASE;
                    }else if(m_collator.compare(subPatt, subPatt.toLowerCase(locale)) == 0){
                       diff[1= LOWER_CASE; 
                    }
                    
                    if(((diff[0== UPPER_CASE&& diff[1== LOWER_CASE)) ||
                       ((diff[0== LOWER_CASE&& diff[1== UPPER_CASE))){        
                        return diff;
                    }else{// not case diff
                      continue
                    }  
                }else{
                    continue
                }
                    
           }
        }
                           
  }
  
  
 // Return a mask for the part of the order we're interested in
    private static final int getMask(final int strength) {
        switch (strength) {
            case Collator.PRIMARY:
                return 0xFFFF0000;
            case Collator.SECONDARY:
                return 0xFFFFFF00;
            default
                return 0xFFFFFFFF;
        }
    }
    //get collation element with given strength
    // from the element with max strength
  private final int getElement(int maxStrengthElement){
    
    return (maxStrengthElement & m_mask);
  }  

}//StringComparable
13. 18. Collator
13. 18. 1. Use RuleBasedCollator
13. 18. 2. Collator based compare
13. 18. 3. CollationKey and Collator.getInstance
13. 18. 4. Comparing Strings in a Locale-Independent Way
13. 18. 5. International friendly string comparison with case-order
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.