1 61 62 63 package org.jaxen.function; 64 65 import java.util.HashMap ; 66 import java.util.List ; 67 import java.util.Map ; 68 69 import org.jaxen.Context; 70 import org.jaxen.Function; 71 import org.jaxen.FunctionCallException; 72 import org.jaxen.Navigator; 73 74 111 public class TranslateFunction implements Function 112 { 113 114 117 118 121 public TranslateFunction() {} 122 123 124 138 public Object call(Context context, 139 List args) throws FunctionCallException 140 { 141 if (args.size() == 3) { 142 return evaluate( args.get(0), 143 args.get(1), 144 args.get(2), 145 context.getNavigator() ); 146 } 147 148 throw new FunctionCallException( "translate() requires three arguments." ); 149 } 150 151 171 public static String evaluate(Object strArg, 172 Object fromArg, 173 Object toArg, 174 Navigator nav) throws FunctionCallException 175 { 176 String inStr = StringFunction.evaluate( strArg, nav ); 177 String fromStr = StringFunction.evaluate( fromArg, nav ); 178 String toStr = StringFunction.evaluate( toArg, nav ); 179 180 Map characterMap = new HashMap (); 182 String [] fromCharacters = toUnicodeCharacters(fromStr); 183 String [] toCharacters = toUnicodeCharacters(toStr); 184 int fromLen = fromCharacters.length; 185 int toLen = toCharacters.length; 186 for ( int i = 0; i < fromLen; i++ ) { 187 String cFrom = fromCharacters[i]; 188 if ( characterMap.containsKey( cFrom ) ) { 189 continue; 191 } 192 193 if ( i < toLen ) { 194 characterMap.put( cFrom, toCharacters[i] ); 196 } 197 else { 198 characterMap.put( cFrom, null ); 200 } 201 } 202 203 StringBuffer outStr = new StringBuffer ( inStr.length() ); 205 String [] inCharacters = toUnicodeCharacters(inStr); 206 int inLen = inCharacters.length; 207 for ( int i = 0; i < inLen; i++ ) { 208 String cIn = inCharacters[i]; 209 if ( characterMap.containsKey( cIn ) ) { 210 String cTo = (String ) characterMap.get( cIn ); 211 if ( cTo != null ) { 212 outStr.append( cTo ); 213 } 214 } 215 else { 216 outStr.append( cIn ); 217 } 218 } 219 220 return outStr.toString(); 221 } 222 223 private static String [] toUnicodeCharacters(String s) throws FunctionCallException { 224 225 String [] result = new String [s.length()]; 226 int stringLength = 0; 227 for (int i = 0; i < s.length(); i++) { 228 char c1 = s.charAt(i); 229 if (isHighSurrogate(c1)) { 230 try { 231 char c2 = s.charAt(i+1); 232 if (isLowSurrogate(c2)) { 233 result[stringLength] = (c1 + "" + c2).intern(); 234 i++; 235 } 236 else { 237 throw new FunctionCallException("Mismatched surrogate pair in translate function"); 238 } 239 } 240 catch (StringIndexOutOfBoundsException ex) { 241 throw new FunctionCallException("High surrogate without low surrogate at end of string passed to translate function"); 242 } 243 } 244 else { 245 result[stringLength]=String.valueOf(c1).intern(); 246 } 247 stringLength++; 248 } 249 250 if (stringLength == result.length) return result; 251 252 String [] trimmed = new String [stringLength]; 254 System.arraycopy(result, 0, trimmed, 0, stringLength); 255 return trimmed; 256 257 } 258 259 private static boolean isHighSurrogate(char c) { 260 return c >= 0xD800 && c <= 0xDBFF; 261 } 262 263 private static boolean isLowSurrogate(char c) { 264 return c >= 0xDC00 && c <= 0xDFFF; 265 } 266 267 } | Popular Tags |