1 28 29 package org.jibx.binding.model; 30 31 import java.lang.reflect.Constructor ; 32 import java.lang.reflect.InvocationTargetException ; 33 import java.lang.reflect.Method ; 34 35 import org.jibx.binding.util.StringArray; 36 37 43 44 public class StringAttributes extends AttributeBase 45 { 46 47 public static final StringArray s_allowedAttributes = 48 new StringArray(new String [] { "default", "deserializer", 49 "serializer" }); 50 52 55 private static final String [] SERIALIZER_SIGNATURE_VARIANTS = 57 { 58 "Lorg/jibx/runtime/IMarshallingContext;", 59 "Ljava/lang/Object;", 60 "" 61 }; 62 63 private static final String [] DESERIALIZER_SIGNATURES = 65 { 66 "(Ljava/lang/String;Lorg/jibx/runtime/IUnmarshallingContext;)", 67 "(Ljava/lang/String;Ljava/lang/Object;)", 68 "(Ljava/lang/String;)" 69 }; 70 71 private static final String STRING_CONSTRUCTOR_SIGNATURE = 73 "(Ljava/lang/String;)"; 74 75 private static final Class [] STRING_CONSTRUCTOR_ARGUMENT_CLASSES = 77 { 78 java.lang.String .class 79 }; 80 81 84 85 private String m_formatName; 86 87 88 private String m_defaultText; 89 90 91 private String m_serializerName; 92 93 94 private String m_deserializerName; 95 96 97 private FormatElement m_baseFormat; 98 99 100 private IClass m_typeClass; 101 102 103 private Object m_default; 104 105 106 private IClassItem m_serializerItem; 107 108 109 private IClassItem m_deserializerItem; 110 111 114 public StringAttributes() {} 115 116 124 public void setType(IClass type) { 125 m_typeClass = type; 126 } 127 128 133 public IClass getType() { 134 return m_typeClass; 135 } 136 137 142 public String getFormatName() { 143 return m_formatName; 144 } 145 146 151 public void setFormatName(String name) { 152 m_formatName = name; 153 } 154 155 160 public String getDefaultText() { 161 return m_defaultText; 162 } 163 164 170 public Object getDefault() { 171 return m_default; 172 } 173 174 179 public void setDefaultText(String value) { 180 m_defaultText = value; 181 } 182 183 189 public String getSerializerName() { 190 return m_serializerName; 191 } 192 193 199 public IClassItem getSerializer() { 200 return m_serializerItem; 201 } 202 203 208 public void setSerializerName(String name) { 209 m_serializerName = name; 210 } 211 212 218 public String getDeserializerName() { 219 return m_serializerName; 220 } 221 222 228 public IClassItem getDeserializer() { 229 return m_deserializerItem; 230 } 231 232 237 public void setDeserializerName(String name) { 238 m_deserializerName = name; 239 } 240 241 247 public FormatElement getBaseFormat() { 248 return m_baseFormat; 249 } 250 251 254 public void prevalidate(ValidationContext vctx) { 255 256 if (m_typeClass == null) { 258 vctx.addFatal("Missing type information for conversion to string"); 259 } else { 260 261 DefinitionContext dctx = vctx.getDefinitions(); 263 if (m_formatName == null) { 264 m_baseFormat = dctx.getBestFormat(m_typeClass); 265 } else { 266 m_baseFormat = dctx.getNamedFormat(m_formatName); 267 } 268 269 String tname = m_typeClass.getName(); 271 if (vctx.isOutBinding()) { 272 if (m_serializerName != null) { 273 274 String [] tsigs = ClassUtils. 276 getSignatureVariants(tname, vctx); 277 int vcnt = SERIALIZER_SIGNATURE_VARIANTS.length; 278 String [] msigs = new String [tsigs.length * vcnt]; 279 for (int i = 0; i < tsigs.length; i++) { 280 for (int j = 0; j < vcnt; j++) { 281 msigs[i*vcnt + j] = "(" + tsigs[i] + 282 SERIALIZER_SIGNATURE_VARIANTS[j] + 283 ")Ljava/lang/String;"; 284 } 285 } 286 287 m_serializerItem = ClassUtils. 289 findStaticMethod(m_serializerName, msigs, vctx); 290 if (m_serializerItem == null) { 291 vctx.addError("Static serializer method " + 292 m_serializerName + " not found"); 293 } 294 295 } else { 296 297 FormatElement ances = m_baseFormat; 299 while (ances != null) { 300 m_serializerItem = ances.getSerializer(); 301 if (m_serializerItem == null) { 302 ances = ances.getBaseFormat(); 303 } else { 304 break; 305 } 306 } 307 if (m_serializerItem == null) { 308 m_serializerItem = m_typeClass.getMethod("toString", 309 "()Ljava/lang/String;"); 310 if (m_serializerItem == null) { 311 throw new IllegalStateException 312 ("Internal error: toString method not found"); 313 } 314 } 315 } 316 } 317 if (vctx.isInBinding() || m_defaultText != null) { 318 if (m_deserializerName != null) { 319 320 m_deserializerItem = ClassUtils. 322 findStaticMethod(m_deserializerName, 323 DESERIALIZER_SIGNATURES, vctx); 324 if (m_deserializerItem == null) { 325 vctx.addError("Static deserializer method " + 326 m_deserializerName + " not found"); 327 } else { 328 String result = m_deserializerItem.getTypeName(); 329 if (!ClassUtils.isAssignable(result, tname, vctx)) { 330 vctx.addError("Static deserializer method " + 331 m_deserializerName + 332 " has incompatible result type"); 333 } 334 } 335 336 } else { 337 338 FormatElement ances = m_baseFormat; 340 while (ances != null) { 341 m_deserializerItem = ances.getDeserializer(); 342 if (m_deserializerItem == null) { 343 ances = ances.getBaseFormat(); 344 } else { 345 break; 346 } 347 } 348 if (m_deserializerItem == null && 349 !"java.lang.Object".equals(tname)) { 350 351 m_deserializerItem = m_typeClass. 353 getInitializerMethod(STRING_CONSTRUCTOR_SIGNATURE); 354 if (m_deserializerItem == null) { 355 StringBuffer buff = new StringBuffer (); 356 buff.append("Need deserializer or constructor "); 357 buff.append("from string"); 358 if (!vctx.isInBinding()) { 359 buff.append(" for default value of type "); 360 buff.append(tname); 361 } else { 362 buff.append(" for type "); 363 buff.append(tname); 364 } 365 vctx.addError(buff.toString()); 366 } 367 } 368 } 369 } 370 371 if (m_defaultText != null && m_deserializerItem != null) { 373 374 String cname = m_deserializerItem.getOwningClass().getName(); 376 Class clas = ClassUtils.loadClass(cname); 377 Exception ex = null; 378 boolean construct = false; 379 try { 380 if (clas == null) { 381 vctx.addError("Unable to load class " + cname + 382 " for converting default value of type " + tname); 383 } else if (m_deserializerItem.isInitializer()) { 384 385 construct = true; 387 Constructor cons = clas.getConstructor 388 (STRING_CONSTRUCTOR_ARGUMENT_CLASSES); 389 try { 390 cons.setAccessible(true); 391 } catch (Exception e) { } 392 Object [] args = new Object [1]; 393 args[0] = m_defaultText; 394 m_default = cons.newInstance(args); 395 396 } else { 397 398 String mname = m_deserializerItem.getName(); 400 Method deser = clas.getDeclaredMethod(mname, 401 STRING_CONSTRUCTOR_ARGUMENT_CLASSES); 402 try { 403 deser.setAccessible(true); 404 } catch (Exception e) { } 405 Object [] args = new Object [1]; 406 args[0] = m_defaultText; 407 m_default = deser.invoke(null, args); 408 409 } 410 } catch (SecurityException e) { 411 StringBuffer buff = new StringBuffer ("Unable to access "); 412 if (construct) { 413 buff.append("constructor from string"); 414 } else { 415 buff.append("deserializer "); 416 buff.append(m_deserializerName); 417 } 418 buff.append(" for converting default value of type "); 419 buff.append(tname); 420 vctx.addError(buff.toString()); 421 } catch (NoSuchMethodException e) { 422 StringBuffer buff = new StringBuffer ("Unable to find "); 423 if (construct) { 424 buff.append("constructor from string"); 425 } else { 426 buff.append("deserializer "); 427 buff.append(m_deserializerName); 428 } 429 buff.append(" for converting default value of type "); 430 buff.append(tname); 431 vctx.addError(buff.toString()); 432 } catch (IllegalArgumentException e) { 433 ex = e; 434 } catch (InstantiationException e) { 435 ex = e; 436 } catch (IllegalAccessException e) { 437 ex = e; 438 } catch (InvocationTargetException e) { 439 ex = e; 440 } finally { 441 if (ex != null) { 442 StringBuffer buff = new StringBuffer ("Error calling "); 443 if (construct) { 444 buff.append("constructor from string"); 445 } else { 446 buff.append("deserializer "); 447 buff.append(m_deserializerName); 448 } 449 buff.append(" for converting default value of type "); 450 buff.append(tname); 451 vctx.addError(buff.toString()); 452 } 453 } 454 } 455 } 456 super.prevalidate(vctx); 457 } 458 } | Popular Tags |