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