17935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*
27935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *******************************************************************************
37935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Copyright (C) 2003-2010, International Business Machines Corporation and    *
47935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * others. All Rights Reserved.                                                *
57935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *******************************************************************************
67935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert*/
77935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpackage com.ibm.icu.dev.test.stringprep;
87935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
97935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.lang.reflect.InvocationTargetException;
117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.lang.reflect.Method;
127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.ICUResourceBundle;
147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.lang.UCharacter;
157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.lang.UCharacterDirection;
167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.text.StringPrepParseException;
177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.text.UCharacterIterator;
187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.text.UnicodeSet;
197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/**
217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @author ram
227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *
237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * To change the template for this generated type comment go to
247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Window>Preferences>Java>Code Generation>Code and Comments
257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */
267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpublic class NamePrepTransform {
277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final NamePrepTransform transform = new NamePrepTransform();
297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private UnicodeSet labelSeparatorSet;
317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private UnicodeSet prohibitedSet;
327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private UnicodeSet unassignedSet;
337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private MapTransform mapTransform;
347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int NONE = 0;
357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int ALLOW_UNASSIGNED = 1;
367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private NamePrepTransform(){
387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // load the resource bundle
397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ICUResourceBundle bundle = (ICUResourceBundle)ICUResourceBundle.getBundleInstance("com/ibm/icu/dev/data/testdata","idna_rules", NamePrepTransform.class.getClassLoader(), true);
407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String  mapRules      = bundle.getString("MapNoNormalization");
417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        mapRules             += bundle.getString("MapNFKC");
427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // disable
437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        mapTransform          = new MapTransform("CaseMap", mapRules, 0 /*Transliterator.FORWARD*/);
447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        labelSeparatorSet     = new UnicodeSet(bundle.getString("LabelSeparatorSet"));
457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        prohibitedSet         = new UnicodeSet(bundle.getString("ProhibitedSet"));
467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        unassignedSet         = new UnicodeSet(bundle.getString("UnassignedSet"));
477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final NamePrepTransform getInstance(){
507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return transform;
517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static boolean isLabelSeparator(int ch){
537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return transform.labelSeparatorSet.contains(ch);
547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     /*
577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       1) Map -- For each character in the input, check if it has a mapping
587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          and, if so, replace it with its mapping.
597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       2) Normalize -- Possibly normalize the result of step 1 using Unicode
617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          normalization.
627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       3) Prohibit -- Check for any characters that are not allowed in the
647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          output.  If any are found, return an error.
657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       4) Check bidi -- Possibly check for right-to-left characters, and if
677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          any are found, make sure that the whole string satisfies the
687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          requirements for bidirectional strings.  If the string does not
697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          satisfy the requirements for bidirectional strings, return an
707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          error.
717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          [Unicode3.2] defines several bidirectional categories; each character
727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert           has one bidirectional category assigned to it.  For the purposes of
737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert           the requirements below, an "RandALCat character" is a character that
747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert           has Unicode bidirectional categories "R" or "AL"; an "LCat character"
757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert           is a character that has Unicode bidirectional category "L".  Note
767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert           that there are many characters which fall in neither of the above
797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert           definitions; Latin digits (<U+0030> through <U+0039>) are examples of
807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert           this because they have bidirectional category "EN".
817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert           In any profile that specifies bidirectional character handling, all
837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert           three of the following requirements MUST be met:
847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert           1) The characters in section 5.8 MUST be prohibited.
867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert           2) If a string contains any RandALCat character, the string MUST NOT
887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert              contain any LCat character.
897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert           3) If a string contains any RandALCat character, a RandALCat
917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert              character MUST be the first character of the string, and a
927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert              RandALCat character MUST be the last character of the string.
937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    */
947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public boolean isReady() {
967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return mapTransform.isReady();
977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public StringBuffer prepare(UCharacterIterator src,
1007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                       int options)
1017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                       throws StringPrepParseException{
1027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             return prepare(src.getText(),options);
1037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private String map ( String src, int options)
1067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                throws StringPrepParseException{
1077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // map
1087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        boolean allowUnassigned =  ((options & ALLOW_UNASSIGNED)>0);
1097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // disable test
1107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String caseMapOut = mapTransform.transliterate(src);
1117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        UCharacterIterator iter = UCharacterIterator.getInstance(caseMapOut);
1127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int ch;
1137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        while((ch=iter.nextCodePoint())!=UCharacterIterator.DONE){
1147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(transform.unassignedSet.contains(ch)==true && allowUnassigned ==false){
1157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                throw new StringPrepParseException("An unassigned code point was found in the input",
1167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                         StringPrepParseException.UNASSIGNED_ERROR);
1177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
1187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
1197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return caseMapOut;
1207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public StringBuffer prepare(String src,int options)
1227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                   throws StringPrepParseException{
1237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int ch;
1257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String mapOut = map(src,options);
1267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        UCharacterIterator iter = UCharacterIterator.getInstance(mapOut);
1277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int direction=UCharacterDirection.CHAR_DIRECTION_COUNT,
1297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            firstCharDir=UCharacterDirection.CHAR_DIRECTION_COUNT;
1307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int rtlPos=-1, ltrPos=-1;
1317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        boolean rightToLeft=false, leftToRight=false;
1327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        while((ch=iter.nextCodePoint())!= UCharacterIterator.DONE){
1347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(transform.prohibitedSet.contains(ch)==true && ch!=0x0020){
1377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                throw new StringPrepParseException("A prohibited code point was found in the input",
1387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                         StringPrepParseException.PROHIBITED_ERROR,
1397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                         iter.getText(),iter.getIndex());
1407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
1417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            direction = UCharacter.getDirection(ch);
1437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(firstCharDir == UCharacterDirection.CHAR_DIRECTION_COUNT){
1447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                firstCharDir = direction;
1457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
1467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(direction == UCharacterDirection.LEFT_TO_RIGHT){
1477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                leftToRight = true;
1487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                ltrPos = iter.getIndex()-1;
1497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
1507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(direction == UCharacterDirection.RIGHT_TO_LEFT || direction == UCharacterDirection.RIGHT_TO_LEFT_ARABIC){
1517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                rightToLeft = true;
1527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                rtlPos = iter.getIndex()-1;
1537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
1547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
1557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // satisfy 2
1577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if( leftToRight == true && rightToLeft == true){
1587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            throw new StringPrepParseException("The input does not conform to the rules for BiDi code points.",
1597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                     StringPrepParseException.CHECK_BIDI_ERROR,iter.getText(),(rtlPos>ltrPos) ? rtlPos : ltrPos);
1607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
1617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        //satisfy 3
1637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if( rightToLeft == true &&
1647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            !((firstCharDir == UCharacterDirection.RIGHT_TO_LEFT || firstCharDir == UCharacterDirection.RIGHT_TO_LEFT_ARABIC) &&
1657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            (direction == UCharacterDirection.RIGHT_TO_LEFT || direction == UCharacterDirection.RIGHT_TO_LEFT_ARABIC))
1667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert           ){
1677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            throw new StringPrepParseException("The input does not conform to the rules for BiDi code points.",
1687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                      StringPrepParseException.CHECK_BIDI_ERROR,iter.getText(),(rtlPos>ltrPos) ? rtlPos : ltrPos);
1697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
1707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return new StringBuffer(mapOut);
1727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static class MapTransform {
1767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        private Object translitInstance;
1777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        private Method translitMethod;
1787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        private boolean isReady;
1797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        MapTransform(String id, String rule, int direction) {
1817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            isReady = initialize(id, rule, direction);
1827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
1837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        boolean initialize(String id, String rule, int direction) {
1857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            try {
1867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                Class cls = Class.forName("com.ibm.icu.text.Transliterator");
1877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                Method createMethod = cls.getMethod("createFromRules", String.class, String.class, Integer.TYPE);
1887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                translitInstance = createMethod.invoke(null, id, rule, Integer.valueOf(direction));
1897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                translitMethod = cls.getMethod("transliterate", String.class);
1907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } catch (Throwable e) {
1917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return false;
1927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
1937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return true;
1947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
1957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        boolean isReady() {
1977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return isReady;
1987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
1997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String transliterate(String text) {
2017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (!isReady) {
2027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                throw new IllegalStateException("Transliterator is not ready");
2037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
2047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String result = null;
2057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            try {
2067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                result = (String)translitMethod.invoke(translitInstance, text);
2077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } catch (InvocationTargetException ite) {
2087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                throw new RuntimeException(ite);
2097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } catch (IllegalAccessException iae) {
2107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                throw new RuntimeException(iae);
2117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
2127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return result;
2137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
2147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
2157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert}
216