1 16 package org.directwebremoting.dwrp; 17 18 import java.util.Arrays ; 19 import java.util.Collection ; 20 import java.util.Collections ; 21 import java.util.HashMap ; 22 import java.util.Iterator ; 23 import java.util.List ; 24 import java.util.Map ; 25 26 import org.directwebremoting.extend.Converter; 27 import org.directwebremoting.extend.ConverterManager; 28 import org.directwebremoting.extend.InboundContext; 29 import org.directwebremoting.extend.InboundVariable; 30 import org.directwebremoting.extend.MarshallException; 31 import org.directwebremoting.extend.NamedConverter; 32 import org.directwebremoting.extend.OutboundContext; 33 import org.directwebremoting.extend.OutboundVariable; 34 import org.directwebremoting.extend.TypeHintContext; 35 import org.directwebremoting.util.LocalUtil; 36 import org.directwebremoting.util.Logger; 37 import org.directwebremoting.util.Messages; 38 39 43 public class DefaultConverterManager implements ConverterManager 44 { 45 48 public void addConverterType(String id, String className) 49 { 50 if (!LocalUtil.isJavaIdentifier(id)) 51 { 52 log.error("Illegal identifier: '" + id + "'"); 53 return; 54 } 55 56 Class clazz = LocalUtil.classForName(id, className, Converter.class); 57 if (clazz != null) 58 { 59 log.debug("- adding converter type: " + id + " = " + clazz.getName()); 60 converterTypes.put(id, clazz); 61 } 62 } 63 64 67 public void addConverter(String match, String type, Map params) throws IllegalArgumentException , InstantiationException , IllegalAccessException 68 { 69 Class clazz = (Class ) converterTypes.get(type); 70 if (clazz == null) 71 { 72 log.info("Probably not an issue: " + match + " is not available so the " + type + " converter will not load. This is only an problem if you wanted to use it."); 73 return; 74 } 75 76 Converter converter = (Converter) clazz.newInstance(); 77 converter.setConverterManager(this); 78 79 LocalUtil.setParams(converter, params, ignore); 80 81 addConverter(match, converter); 83 } 84 85 88 public void addConverter(String match, Converter converter) throws IllegalArgumentException 89 { 90 Converter other = (Converter) converters.get(match); 92 if (other != null) 93 { 94 log.warn("Clash of converters for " + match + ". Using " + converter.getClass().getName() + " in place of " + other.getClass().getName()); 95 } 96 97 log.debug("- adding converter: " + LocalUtil.getShortClassName(converter.getClass()) + " for " + match); 98 converters.put(match, converter); 99 } 100 101 104 public Collection getConverterMatchStrings() 105 { 106 return Collections.unmodifiableSet(converters.keySet()); 107 } 108 109 112 public Converter getConverterByMatchString(String match) 113 { 114 return (Converter) converters.get(match); 115 } 116 117 120 public boolean isConvertable(Class paramType) 121 { 122 return getConverter(paramType) != null; 123 } 124 125 128 public Object convertInbound(Class paramType, InboundVariable iv, InboundContext inctx, TypeHintContext incc) throws MarshallException 129 { 130 Object converted = inctx.getConverted(iv, paramType); 131 if (converted == null) 132 { 133 Converter converter = getNamedConverter(paramType, iv.getType()); 137 138 if (converter == null) 141 { 142 converter = getConverter(paramType); 143 } 144 145 if (converter == null) 146 { 147 throw new MarshallException(paramType, Messages.getString("DefaultConverterManager.MissingConverter", paramType)); 148 } 149 150 if (iv.isNull()) 154 { 155 return null; 156 } 157 158 inctx.pushContext(incc); 159 converted = converter.convertInbound(paramType, iv, inctx); 160 inctx.popContext(); 161 } 162 163 return converted; 164 } 165 166 169 public OutboundVariable convertOutbound(Object object, OutboundContext outctx) throws MarshallException 170 { 171 if (object == null) 172 { 173 return new SimpleOutboundVariable("null", outctx, true); 174 } 175 176 OutboundVariable ov = outctx.get(object); 178 if (ov != null) 179 { 180 return ov.getReferenceVariable(); 182 } 183 184 Converter converter = getConverter(object); 186 if (converter == null) 187 { 188 log.error(Messages.getString("DefaultConverterManager.MissingConverter", object.getClass().getName())); 189 return new SimpleOutboundVariable("null", outctx, true); 190 } 191 192 return converter.convertOutbound(object, outctx); 193 } 194 195 198 public void setExtraTypeInfo(TypeHintContext thc, Class type) 199 { 200 extraTypeInfoMap.put(thc, type); 201 } 202 203 206 public Class getExtraTypeInfo(TypeHintContext thc) 207 { 208 Class type = (Class ) extraTypeInfoMap.get(thc); 209 return type; 210 } 211 212 215 public void setConverters(Map converters) 216 { 217 this.converters = converters; 218 } 219 220 227 private Converter getConverter(Object object) 228 { 229 if (object == null) 230 { 231 return getConverter(Void.TYPE); 232 } 233 234 return getConverter(object.getClass()); 235 } 236 237 245 protected Converter getNamedConverter(Class paramType, String type) throws MarshallException 246 { 247 if (type.startsWith("Object_")) 248 { 249 String javascriptClassName = type.substring("Object_".length()); 251 252 Iterator it = converters.entrySet().iterator(); 254 while (it.hasNext()) 255 { 256 Map.Entry entry = (Map.Entry ) it.next(); 257 String match = (String ) entry.getKey(); 258 Converter conv = (Converter) entry.getValue(); 259 260 if (conv instanceof NamedConverter) 262 { 263 NamedConverter boConv = (NamedConverter) conv; 264 if (boConv.getJavascript() != null && boConv.getJavascript().equals(javascriptClassName)) 265 { 266 try 270 { 271 Class inboundClass = LocalUtil.classForName(match); 272 if (paramType.isAssignableFrom(inboundClass)) 273 { 274 boConv.setInstanceType(inboundClass); 280 return boConv; 281 } 282 } 283 catch (ClassNotFoundException ex) 284 { 285 throw new MarshallException(paramType, ex); 286 } 287 } 288 } 289 } 290 } 291 292 return null; 293 } 294 295 299 private Converter getConverter(Class paramType) 300 { 301 Converter converter = getConverterAssignableFrom(paramType); 303 if (converter != null) 304 { 305 return converter; 306 } 307 308 String lookup = paramType.getName(); 309 310 if (lookup.startsWith("$Proxy")) 313 { 314 converter = (Converter) converters.get("$Proxy*"); 315 if (converter != null) 316 { 317 return converter; 318 } 319 } 320 321 while (true) 322 { 323 converter = (Converter) converters.get(lookup + ".*"); 325 if (converter != null) 326 { 327 return converter; 328 } 329 330 converter = (Converter) converters.get(lookup + '*'); 332 if (converter != null) 333 { 334 return converter; 335 } 336 337 if (lookup.length() == 0) 339 { 340 break; 341 } 342 343 int lastdot = lookup.lastIndexOf('.'); 345 if (lastdot != -1) 346 { 347 lookup = lookup.substring(0, lastdot); 348 } 349 else 350 { 351 int arrayMarkers = 0; 352 while (lookup.charAt(arrayMarkers) == '[') 353 { 354 arrayMarkers++; 355 } 356 357 if (arrayMarkers == 0) 358 { 359 break; 362 } 363 364 lookup = lookup.substring(arrayMarkers - 1, arrayMarkers + 1); 366 367 converter = (Converter) converters.get(lookup); 369 if (converter != null) 370 { 371 return converter; 372 } 373 } 374 } 375 376 return null; 377 } 378 379 383 private Converter getConverterAssignableFrom(Class paramType) 384 { 385 if (paramType == null) 386 { 387 return null; 388 } 389 390 String lookup = paramType.getName(); 391 392 Converter converter = (Converter) converters.get(lookup); 394 if (converter != null) 395 { 396 return converter; 397 } 398 399 Class [] interfaces = paramType.getInterfaces(); 401 for (int i = 0; i < interfaces.length; i++) 402 { 403 converter = getConverterAssignableFrom(interfaces[i]); 404 if (converter != null) 405 { 406 converters.put(lookup, converter); 407 return converter; 408 } 409 } 410 411 converter = getConverterAssignableFrom(paramType.getSuperclass()); 413 if (converter != null) 414 { 415 converters.put(lookup, converter); 416 } 417 418 return converter; 419 } 420 421 424 private Map extraTypeInfoMap = new HashMap (); 425 426 429 private static final Logger log = Logger.getLogger(DefaultConverterManager.class); 430 431 434 private Map converterTypes = new HashMap (); 435 436 439 private Map converters = new HashMap (); 440 441 445 private static List ignore = Arrays.asList(new String [] { "converter", "match" }); 446 } 447 | Popular Tags |