Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replacement for Normalizer.getClass(c) method in Java 6

Tags:

java

The getClass(char c) method from Normalizer class seems to be missing from Java 6 onwards.

This method is present in our legacy code and is being used as shown below. We need to migrate it to Java 6. Any suggestions on how it can be replaced?

import sun.text.Normalizer;

 /**
 * Returns an array of strings that have all the possible
 * permutations of the characters in the input string.
 * This is used to get a list of all possible orderings
 * of a set of combining marks. Note that some of the permutations
 * are invalid because of combining class collisions, and these
 * possibilities must be removed because they are not canonically
 * equivalent.
 */
private String[] producePermutations(String input) {
    if (input.length() == 1)
        return new String[] {input};

    if (input.length() == 2) {
        if (getClass(input.charAt(1)) ==
            getClass(input.charAt(0))) {
            return new String[] {input};
        }
        String[] result = new String[2];
        result[0] = input;
        StringBuffer sb = new StringBuffer(2);
        sb.append(input.charAt(1));
        sb.append(input.charAt(0));
        result[1] = sb.toString();
        return result;
    }

    int length = 1;
    for(int x=1; x<input.length(); x++)
        length = length * (x+1);

    String[] temp = new String[length];

    int combClass[] = new int[input.length()];
    for(int x=0; x<input.length(); x++)
        combClass[x] = getClass(input.charAt(x));

    // For each char, take it out and add the permutations
    // of the remaining chars
    int index = 0;
loop:   for(int x=0; x<input.length(); x++) {
        boolean skip = false;
        for(int y=x-1; y>=0; y--) {
            if (combClass[y] == combClass[x]) {
                continue loop;
            }
        }
        StringBuffer sb = new StringBuffer(input);
        String otherChars = sb.delete(x, x+1).toString();
        String[] subResult = producePermutations(otherChars);

        String prefix = input.substring(x, x+1);
        for(int y=0; y<subResult.length; y++)
            temp[index++] =  prefix + subResult[y];
    }
    String[] result = new String[index];
    for (int x=0; x<index; x++)
        result[x] = temp[x];
    return result;
}

private int getClass(char c) {
    return Normalizer.getClass(c);
}
like image 222
dazzle Avatar asked Jan 14 '15 08:01

dazzle


3 Answers

Your code snippet, as others have pointed out, is sun.text.Normalizer and not java.text.Normalizer. In Java 6 I see that sun.text.Normalizer has a method called getCombiningClass(int ch) which is described as "Returns the combining class of the given character" despite taking an int and not a char. This is probably the method you are looking for.

I should note that, being a sun.* class, these sorts of methods are subject to these sorts of changes (renaming, disappearing) with no notice, and you use them at your own risk. Caveat coder!

like image 67
dcsohl Avatar answered Nov 19 '22 18:11

dcsohl


In Java 6, the method was renamed to getCharacterClass, and the parameter was changed from a char to an int, because that sort of replacement was done everywhere to accommodate Unicode characters with values greater than 65,535.

A method from a package that started with sun should never have been used in the first place. That's probably why the call is in a separate method, in case it needs to be rewritten if the method is removed. Unfortunately, I can't find an equivalent in the public Java API, so the replacement will have to be either written from scratch or undocumented.

like image 39
tbodt Avatar answered Nov 19 '22 16:11

tbodt


Normalizer from java.text has no same functionalities of Normalizer from sun.text

Based only on this piece of code you entered, the easy way to do what you want is use ICU4J dependency. If you use maven, like this:

<dependency>
    <groupId>com.ibm.icu</groupId>
    <artifactId>icu4j</artifactId>
    <version>4.6</version>
</dependency>

Then, you can write a class like this:

package com.ibm.icu.text;

public class Normalizer {

    public static final int getClass(final char ch) {
        final int value = DecompData.canonClass.elementAt(ch);
        return value >= 0 ? value : value + 256;
    }

}

Since DecompData has package-private visibility, create Normalizer in same package in you application.

like image 1
Bruno Ribeiro Avatar answered Nov 19 '22 16:11

Bruno Ribeiro